ThinkPHP在Nginx下无法隐藏index.php的根本原因是服务器配置错误:root未指向public目录、location ~ .php$块中缺失QUERY_STRING传递或未禁用fastcgi_split_path_info、runtime目录权限不足,三者导致路由无法正确转发或解析。

ThinkPHP 在 Nginx 下无法隐藏 index.php,根本不是框架问题,而是 Nginx 没把请求正确转给 public/index.php——rewrite 规则写错、fastcgi_split_path_info 干扰、或 root 指向错误,三者占了 90% 的 404 场景。
为什么加了 rewrite 还是 404?检查 location / 和 location ~ \.php$ 是否都配对
只在 location / 里写重写,但 location ~ \.php$ 块里没传参,Nginx 找不到匹配的 PHP 文件就直接 404。TP6 默认用 s= 参数接收路由,必须确保这个参数被带进 FastCGI 环境。
-
location /块必须包含try_files $uri $uri/ /index.php?s=$uri&$args;或等效的if + rewrite(宝塔推荐) -
location ~ \.php$块里必须有这行:fastcgi_param QUERY_STRING $query_string;(不能只靠include fastcgi_params;,它不保证含此行) - 如果用了
alias而非root,$document_root可能为空,导致SCRIPT_FILENAME构造失败——优先用root /path/to/public;
fastcgi_split_path_info 必须禁用,否则 PATH_INFO 错乱
TP5/6 不依赖 Apache 风格的 PATH_INFO 解析,Nginx 默认开启的 fastcgi_split_path_info 会强行拆分路径,把 /user/list 拆成 /index.php + /user/list,再塞进 $_SERVER['PATH_INFO'],结果框架收不到原始路由,或收到错误值。
- 在
location ~ \.php$块中,删掉或注释掉这两行:fastcgi_split_path_info ^(.+\.php)(/.+)$;和fastcgi_param PATH_INFO $fastcgi_path_info; - 确认
public/index.php开头没有硬编码覆盖$_SERVER['PATH_INFO'](上线环境应删除调试用的$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];) - 如果 PHP-FPM 配置里有
security.limit_extensions限制,确保.php在白名单内
宝塔面板下最稳的配置写法(不用 if 也能跑通)
宝塔新版支持更干净的 try_files 写法,比 if (!-e ...) 更安全,且避免因顺序错位失效。关键在于:规则放对位置、root 指向明确、参数不遗漏。
立即学习“PHP免费学习笔记(深入)”;
- 在站点配置的
server块内,**删除所有旧的if或rewrite块**,只保留: -
root /www/wwwroot/your-site/public;(绝对路径,结尾不加斜杠) index index.php;location / { try_files $uri $uri/ /index.php?s=$uri&$args; }location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_pass unix:/tmp/php-cgi.sock; }
runtime 权限不对会导致 debug=false、日志不写、缓存生成失败
很多人改了 config/app.php 的 'debug' => true 却没效果,表面是配置问题,实际常因 runtime/ 不可写,导致框架连 route_cache.php 都生成不了,最终 fallback 到生产模式。
- 运行
ps aux | grep nginx查 Nginx 主进程用户(如www-data或nginx) chgrp www-data runtime && chmod 775 runtime && chmod g+s runtime- 确保
runtime/上级目录(如项目根目录)对 Nginx 用户可执行(x权限),否则无法 traverse 进入 - 清空缓存:
php think clear或手动删runtime/cache/和runtime/route/下文件
真正卡住人的从来不是规则本身,而是 root 指向 public 目录、fastcgi_split_path_info 关闭、以及 runtime 组权限这三点没对齐——少一个,index.php 就藏不住。



















