ThinkPHP默认依赖$_SERVER['PATH_INFO']解析路由,当Nginx未配置fastcgi_param PATH_INFO或运行于Swoole等非CGI环境时该变量为空,导致路由失效;需在public/index.php中手动从REQUEST_URI提取并设置$_SERVER['PATH_INFO'],再确保url_mode匹配且避免重复修改。

ThinkPHP 默认通过服务器环境自动获取 PATH_INFO,但在某些特殊部署环境(比如 CLI 模式、嵌入式 Web 服务器、或 URL 被前端代理多次重写后 PATH_INFO 丢失)下,可能需要在入口文件中手动设置 PATH_INFO,以确保路由正常解析。
为什么需要手动设置 PATH_INFO
PATH_INFO 是 ThinkPHP 解析 URL 路由的关键依据。当服务器未正确传递该变量(如 Nginx 配置缺失 fastcgi_param PATH_INFO $fastcgi_path_info;,或使用 Swoole/Workerman 等非标准 CGI 环境),框架将无法识别模块/控制器/操作,导致 404 或默认首页。
在入口文件中设置 PATH_INFO 的方法
在 public/index.php(或其他自定义入口)中,在引入 ThinkPHP 启动文件前,手动构造并写入 $_SERVER['PATH_INFO']:
- 确保已从原始请求中提取出有效路径(如从
$_SERVER['REQUEST_URI']或命令行参数中截取) - 去除入口脚本名(如
/index.php)、查询字符串(?xxx)和锚点(#xxx) - 以斜杠开头,且不包含域名、端口、协议
- 赋值给
$_SERVER['PATH_INFO'],再调用think\Start::run()
示例代码(适用于简单伪静态路径):
立即学习“PHP免费学习笔记(深入)”;
// public/index.phpdefine('APP_PATH', __DIR__ . '/../app/');
// 手动提取 PATH_INFO(假设访问 URL 是 /index.php/user/profile?id=1)
if (!isset($_SERVER['PATH_INFO']) && isset($_SERVER['REQUEST_URI'])) {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// 去掉入口文件名(支持 /index.php、/admin.php 等)
$scriptName = basename($_SERVER['SCRIPT_NAME']);
if (strpos($path, $scriptName) === 0) {
$path = substr($path, strlen($scriptName));
}
$_SERVER['PATH_INFO'] = $path ?: '/';
}
// 启动框架
require __DIR__ . '/../thinkphp/start.php';
配合 URL 模式使用的注意事项
手动设置 PATH_INFO 后,还需确认应用配置与之匹配:
- 确保
config/app.php中'url_mode' => 1(PATHINFO 模式)或保持默认(ThinkPHP 6+ 默认兼容多种模式) - 若启用路由规则,需保证路由定义能匹配你手动设置的 PATH_INFO 格式(例如
/user/list而非/index.php/user/list) - 避免重复处理:不要在中间件或控制器里再次修改
$_SERVER['PATH_INFO'],以免干扰框架内部解析
调试与验证技巧
快速确认是否生效:
- 在控制器中打印
var_dump($_SERVER['PATH_INFO']);和request()->pathinfo(); - 查看日志中路由匹配过程(开启调试模式后,日志会记录匹配到的路由规则)
- 尝试访问一个已定义的路由地址,观察是否触发对应控制器方法而非 404



















