ThinkPHP切换PATH_INFO模式需框架配置、Nginx设置、PHP环境三者严格对齐:开启config/app.php中'url_route_on'=>true和'url_pathinfo'=>true;Nginx中用fastcgi_split_path_info精准提取PATH_INFO;PHP需放行putenv、ini_set等函数。

ThinkPHP 切换到 PATH_INFO 兼容模式,不是简单改一条规则就能通,而是要框架配置、Nginx 设置、PHP 环境三者严格对齐。尤其在 TP6/TP8 中,PATH_INFO 模式不是默认启用的,必须显式开启并确保底层能正确送达。
明确是否真需要 PATH_INFO 模式
TP6/TP8 默认不依赖 $_SERVER['PATH_INFO'],而是从 $_SERVER['REQUEST_URI'] 解析路由。只有以下情况才需启用:
- 项目中已设置
'url_pathinfo' => true(在config/app.php) - 使用了强依赖 PATH_INFO 的中间件或旧版适配逻辑
- 对接遗留系统,URL 形如
/index.php/module/action必须原样支持 - 云函数或某些网关只允许 PATH_INFO 传参方式
如果只是想隐藏 index.php,用 s= 参数模式更稳,无需 PATH_INFO。
在框架层启用 PATH_INFO 支持
打开 config/app.php,确认以下两项:
立即学习“PHP免费学习笔记(深入)”;
-
'url_route_on' => true(必须开启路由) -
'url_pathinfo' => true(关键!显式启用 PATH_INFO 解析)
其他如'pathinfo_depr' => '/'可保持默认,除非你用下划线分隔(如/user_action)。
⚠️ 注意:TP8 中此项默认为
false,不加这行就等于没开;TP6 默认是true,但升级后可能被覆盖,建议显式写上。
Nginx 配置必须精准提取 PATH_INFO
不能只靠 try_files 或 rewrite,必须在 location ~ \.php$ 块内加入 PATH_INFO 提取逻辑:
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
# 其他 fastcgi_param 保持不变(如 SCRIPT_NAME、QUERY_STRING 等)
}关键点:
-
fastcgi_split_path_info是唯一安全提取方式,禁用所有if ($fastcgi_script_name ~ ...)类正则判断 -
$realpath_root必须启用(不是$document_root),否则自动加载失败且无提示 -
root必须指向public/目录,例如:root /www/wwwroot/myapp/public;
PHP 环境要放行关键函数
PATH_INFO 模式下,TP6/TP8 启动时会调用 putenv() 和 ini_set() 动态设置环境。进宝塔 → PHP 设置 → 禁用函数 → 删除 putenv,ini_set,scandir。
同时检查 php.ini 中 cgi.fix_pathinfo=1(默认开启,不建议改)。
验证是否生效
在 public/index.php 开头加一行临时调试代码:
var_dump($_SERVER['PATH_INFO'] ?? 'MISSING'); exit;
访问类似 /index/user/list 的地址:
- 输出
string(12) "/index/user/list"→ 成功 - 输出
MISSING或空字符串 → Nginx 未提取或SCRIPT_FILENAME路径拼错
不复杂但容易忽略



















