nginx伪静态404核心原因是请求未进入thinkphp6框架,需确保root指向public、location/中配置try_files转发、fastcgi_param使用$document_root,并正确传递path_info;宝塔用户须禁用默认伪静态模板并重启服务。

ThinkPHP 6.0 配置伪静态后 Nginx 报 404,核心问题不是路由写错了,而是请求根本没进框架——Nginx 在文件系统里找 /user/login 这样的路径,找不到就直接返回原生 404,public/index.php 压根没执行。
要解决,必须让所有非真实静态资源的请求,全部转发到 public/index.php,并确保 PHP 层能正确拿到路径信息(如 PATH_INFO)。
✅ 确认问题是否出在 Nginx 层
先做这个验证,别急着改配置:
- 访问
http://your-domain.com/index.php/s=/user/login→ 能打开?说明框架和控制器没问题 - 访问
http://your-domain.com/user/login→ 404?说明 Nginx 没把请求转给index.php - 访问
http://your-domain.com/index.php/route/test(一个不存在的路由)→ 出现 ThinkPHP 的「Route not found」页面?说明框架已接管;如果出现 Nginx 默认 404 页面,且响应头没有X-Powered-By: ThinkPHP,那就确认是 Nginx 配置问题。
✅ Nginx 配置三处硬性要求(缺一不可)
root 必须指向 public 目录
不能是项目根目录(如 /var/www/myapp),必须是:
root /var/www/myapp/public;
location / 块必须含 try_files 转发规则
放在 server { ... } 内,且必须在 location ~ \.php$ 块之前:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
注意:TP6 入口在
public/,所以这里/index.php是对的(因为root已设为public目录)。若你没改root,而是用子目录部署(如example.com/tp6/),则要写成/tp6/public/index.php?$query_string。
fastcgi_param SCRIPT_FILENAME 必须用 $document_root
在 location ~ \.php$ 块中,确保有:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
禁用 $request_filename —— 它在重写后可能指向错误路径,导致静默失败。
✅ PATH_INFO 必须正确传递(TP6 路由依赖它)
即使请求进了 index.php,如果 $_SERVER['PATH_INFO'] 是空的,TP6 就无法解析 /user/login 这段路径。
检查以下两点:
-
location ~ \.php$块中不能有这行(宝塔默认74.conf常见):# try_files $uri =404; ← 必须注释或删除!它会提前截断 pathinfo 请求
-
确保有 PATH_INFO 分离配置(推荐):
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; # 其他 fastcgi_param ... }
测试方法:在 public/index.php 开头加一行:
var_dump($_SERVER['PATH_INFO']); die();
访问 /user/login,应输出字符串 /user/login,不是空、不是 /index.php、也不是 NULL。
✅ 宝塔用户特别注意
别点「伪静态 → ThinkPHP」模板,那是 TP5 风格,对 TP6 无效;
-
进「网站 → 设置 → 伪静态」,清空内容,粘贴:
if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; }(前提是你的站点运行目录已设为
/public) 进「配置文件」,确认
include enable-php.conf;上方已手动加了fastcgi_param PATH_INFO $fastcgi_path_info;,且try_files $uri =404;已被注释。改完后,必须彻底重启 Nginx + 重启 PHP-FPM(不是“重载配置”)。
✅ 其他易忽略点
-
禁用
error_page 404:检查配置中是否有error_page 404 /404.html;,删掉或注释,否则 TP6 的Route::miss()根本没机会执行; -
静态资源被误拦截:开启
'url_route_must' => true后,/static/css/app.css也会走路由。在route/app.php顶部加放行规则:Route::rule(':path^.*\.(js|css|png|jpg|gif|svg|woff2|ttf)$', 'static/'); -
权限问题:PHP-FPM 进程用户(如
www)必须有读取public/index.php的权限,否则静默失败(页面空白或 404); -
路由缓存:
APP_DEBUG = false时,路由会被缓存。改了路由文件后,删掉runtime/route/整个目录。
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











