thinkphp伪静态404主因是nginx rewrite规则错误及fastcgi_split_path_info干扰;需用try_files $uri $uri/ /index.php?$query_string并禁用fastcgi_split_path_info,root指向public,runtime设775且同组,清缓存并重载nginx。

Linux 上 ThinkPHP 伪静态失效,90% 是 Nginx rewrite 规则写错 + fastcgi_split_path_info 干扰导致的,不是框架问题,也不是 PHP 版本不兼容。
为什么去掉 index.php 就 404?关键在 Nginx 的 location 和 PATH_INFO 处理
ThinkPHP(TP5/6)默认用 PATH_INFO 模式解析 URL,比如 /index.php/user/list 中的 /user/list 要传给 $_SERVER['PATH_INFO']。但 Nginx 默认不生成这个变量,而是依赖 fastcgi_split_path_info 拆分 —— 这个机制和 TP 的路由逻辑冲突,会导致 $_SERVER['PATH_INFO'] 为空或错乱,最终路由找不到控制器。
实操建议:
- 删掉或注释掉配置中所有
fastcgi_split_path_info相关行(包括正则匹配和set $path_info等) - 用
try_files替代if (!-e $request_filename):后者在 Nginx 里有性能和语义陷阱,且容易漏掉子目录请求 - 确保
location /块里只有一套主规则,不要和location ~ \.php块里的 rewrite 逻辑叠加
推荐写法(放在 server 块内):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
这条规则会把所有非真实文件/目录的请求,统一转发到 /index.php 并附带原始查询参数,TP 内部再通过 $_SERVER['REQUEST_URI'] 或 $_SERVER['QUERY_STRING'] 自行解析,绕开 PATH_INFO 依赖。
root 必须指向 public/,否则敏感目录可被直接访问
把整个 ThinkPHP 项目(含 application/、config/、runtime/)直接扔进 /var/www/html/,等同于把数据库配置、日志内容全暴露在 HTTP 下——只要访问 http://your.site/application/database.php 就可能下载到明文密码。
实操建议:
- Nginx 的
root指令必须设为项目内public/目录的绝对路径,例如root /var/www/myapp/public; - 确认
public/index.php对 Nginx 用户(如www-data或nginx)可读:ls -l /var/www/myapp/public/index.php - 检查上层目录权限:如果
/var/www/myapp的父目录(如/var/www)对 Nginx 用户不可执行(x),Nginx 无法 traverse 进入public/,会报 403
runtime 目录权限设成 775,且必须和 Nginx 进程同组
设成 755 后常出现 mkdir(): Permission denied,不是因为权限太高,是 Nginx 工作进程用户(如 www-data)不在 runtime 所属组里,或者没 setgid。
实操建议:
- 运行:
chmod -R 775 /var/www/myapp/runtime - 运行:
chgrp -R www-data /var/www/myapp/runtime(将组改为 Nginx 用户所在组) - 运行:
chmod g+s /var/www/myapp/runtime(开启 setgid,确保新生成的子目录自动继承组) - 清空
runtime/下所有缓存:rm -rf /var/www/myapp/runtime/{cache,log,route,view},避免旧缓存干扰
.env 配置和缓存未清会导致 debug 关闭、路由不生效
即使 Nginx 规则全对,.env 里写了 APP_DEBUG=false,或改了路由后没清缓存,都会让新 URL 返回 404 或白屏,你以为是伪静态失败,其实是框架没加载新规则。
实操建议:
- 确认
.env文件在public/同级(即项目根目录),且APP_DEBUG=true、APP_ENV=local - 执行:
php think clear(TP6)或php artisan optimize:clear(TP5.1+) - 若用宝塔面板,记得在「网站设置 → 伪静态」里选「ThinkPHP」并保存,它会自动覆盖你手写的规则,同时清空
runtime/temp/
最常被忽略的一点:Nginx 配置改完必须 nginx -t && systemctl reload nginx,而不是只改文件就以为生效;reload 不等于 restart,它不会中断现有连接,但必须确保语法通过。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











