ThinkPHP 6在phpEnv下404的根本原因是Nginx未将非PHP路径请求转发至index.php:默认配置仅处理.php后缀,缺少location /块中的try_files $uri $uri/ /index.php?$query_string规则,且必须显式设置fastcgi_param SCRIPT_NAME /index.php以确保路由基准路径正确。

ThinkPHP 6 在 phpEnv 环境下报 404,根本原因不是框架没跑起来,而是 Nginx 没把请求正确转发给 index.php —— 它压根没执行路由解析逻辑,直接当静态文件找去了。
为什么 phpEnv 默认配置不兼容 ThinkPHP 6
phpEnv 的 Nginx 配置通常沿用传统 PHP 站点习惯:只对 .php 后缀做 fastcgi_pass,而 TP6 要求所有非资源请求(如 /user/list)都落到 public/index.php 入口,再由框架内部分发。默认配置里没有这条兜底 rewrite,Nginx 就会直接返回 404。
- 检查
access.log,如果看到"GET /user/list HTTP/1.1" 404且无 fastcgi 记录,基本确认是入口未命中 - phpEnv 的
nginx.conf或站点 conf 文件中,location ~ \.php$块存在,但缺少对非 PHP 路径的重写控制 - TP6 的
public/目录必须设为 root,否则index.php找不到或路径错乱
必须加的 location + rewrite 组合
在对应 server 块里,紧挨着 root 指令之后,插入以下配置(注意路径与你的部署一致):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
这条规则的意思是:先尝试找真实文件或目录,找不到就交给 /index.php 处理,并把原始查询参数透传过去。
立即学习“PHP免费学习笔记(深入)”;
-
$uri匹配静态资源(js/css/img),直接返回,不进 PHP -
$uri/匹配目录,避免 403(前提是目录下有 index.html 或 autoindex on) -
/index.php?$query_string是关键:确保?s=/user/list这类 URL 参数能被 TP6 正确读取 - 不要用
rewrite ^(.*)$ /index.php?s=$1 last;—— TP6 已弃用s=参数格式,新版依赖 PATH_INFO 或 QUERY_STRING
fastcgi_param 必须显式传递 SCRIPT_NAME
仅靠 try_files 不够,TP6 依赖 SCRIPT_NAME 判断应用根路径。若漏掉这行,url() 等辅助函数会生成错误链接:
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_NAME /index.php;
}
-
fastcgi_param SCRIPT_NAME必须设为/index.php,不能是空或$fastcgi_script_name,否则 TP6 误判为子目录部署 - 确认
fastcgi.conf中已有fastcgi_param QUERY_STRING $query_string;,否则 GET 参数丢失 - phpEnv 若启用了 PATH_INFO 模式(如
/index.php/user/list),需额外加fastcgi_split_path_info ^(.+?\.php)(/.*)$;和fastcgi_param PATH_INFO $fastcgi_path_info;
验证和调试的关键点
改完配置别急着重启,先做三件事:
- 运行
nginx -t,确认语法无误;phpEnv 的 nginx 可能在D:\phpEnv\nginx\下,路径要写对 - 清空浏览器缓存,或用
curl -I http://localhost/user/list查看真实响应头,排除 301 缓存干扰 - 在
public/index.php开头加file_put_contents('log.txt', print_r($_SERVER, true), FILE_APPEND);,检查REQUEST_URI、SCRIPT_NAME、QUERY_STRING是否符合预期
最易被忽略的是 SCRIPT_NAME 的值——它决定了 TP6 路由解析的基准路径,设错会导致所有 URL 生成失效,且错误静默,只表现为链接跳转异常或 404。



















