ThinkPHP 8 默认不启用 PATH_INFO,仅当配置 'url_pathinfo' => true 或有特定兼容需求时才需 Nginx 精准支持;须用 fastcgi_split_path_info 提取并注入 PATH_INFO,root 必须指向 public 目录,否则报错。

确认 PATH_INFO 真的需要启用
ThinkPHP 8 默认不走 PATH_INFO,它优先从 $_SERVER['REQUEST_URI'] 或 $_SERVER['QUERY_STRING'] 解析路由。除非你做了以下之一,否则根本不用配 Nginx 的 PATH_INFO:
- 在
config/app.php中显式设置了'url_pathinfo' => true - 用了强依赖
$_SERVER['PATH_INFO']的中间件或老版兼容逻辑 - 部署环境(比如某些云函数网关)只允许用
index.php/xxx这种传参方式
如果只是想让 /admin/user/list 这类 URL 可访问,URL_MODEL => 2(重写模式)配合 try_files + rewrite 就够了,完全绕过 PATH_INFO。
PHP location 块必须用 fastcgi_split_path_info,不能靠 if
if ($fastcgi_script_name ~ ...) 这类正则判断在 Nginx 里是“慢路径”,且匹配失败时 $path_info 为空,直接导致 TP8 报 URL pathinfo not supported 或白屏。正确做法是:
- 把 PHP 处理块写成
location ~ [^/]\.php(/|$) { },避免误匹配静态资源 - 里面只加三行关键指令:
fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;fastcgi_param PATH_INFO $fastcgi_path_info; -
$realpath_root必须启用(不是$document_root),否则 TP8 自动加载器找不到autoload.php
root 必须指向 public/ 目录,子目录部署要改用 alias
这是最常踩的坑:Nginx root 指向项目根目录(如 /var/www/myapp),但 TP8 入口在 public/index.php。结果就是 Class 'think\App' not found,还无任何错误提示。
PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
- 正确写法:
root /var/www/myapp/public;✅ - 子目录部署(如访问
/myapp/)不能用root,得用alias:location /myapp/ { alias /var/www/myapp/public/; }
再单独配 PHP 处理块,SCRIPT_FILENAME必须用$request_filename或完整拼接路径 - 若用
rewrite方案(如rewrite ^/myapp/(.*)$ /myapp/public/index.php?s=/$1 last;),就不用PATH_INFO,也避开了提取逻辑
验证 PATH_INFO 是否真正送达 PHP
别只看 Nginx 配置有没有报错,得实测值是否进到 PHP。在 public/index.php 开头加一行:
var_dump($_SERVER['PATH_INFO'] ?? 'MISSING');
然后访问类似 /index.php/user/list 的地址:
- 输出
string(12) "/user/list"→ 成功 - 输出
MISSING或空字符串 →fastcgi_split_path_info没生效,或SCRIPT_FILENAME拼错了路径 - 输出乱码或截断(尤其含中文时)→ 查
ORIG_PATH_INFO,那是 Nginx 在 URI 含非 ASCII 字符时 fallback 的原始值
TP8 对 PATH_INFO 的依赖很轻,一旦发现它不可靠,框架会自动降级。所以宁可绕过它,也别硬调一堆 if + set 来模拟。


















