nginx伪静态配置错误导致thinkphp路由404,主因是try_files未正确转发请求至index.php;必须用try_files $uri $uri/ /index.php?$query_string;,禁用if判断,确保root指向public、php块含script_filename参数,并通过/index.php/route/test验证框架是否接管请求。

先查Nginx伪静态:try_files规则写错就全挂
ThinkPHP路由404,八成不是你Route::get()写错了,而是Nginx压根没把请求交给index.php——它直接查文件系统,查不到就甩个原生404给你,框架连初始化都没机会跑。
最常见错误是try_files写成/index.php?s=$1或漏掉$query_string。TP8只认QUERY_STRING模式,s=是TP5旧写法,现在会丢$_GET参数,甚至让$_SERVER['PATH_INFO']为空。
- 正确写法必须是:
location / { try_files $uri $uri/ /index.php?$query_string; } - 如果用了子目录部署(比如
https://site.com/app/),location要改成location /app/,且重写目标得是/app/index.php?$query_string - 别在
location /里套if (!-e $request_filename)——Nginx官方已标记为“不推荐”,容易触发重写循环或跳过缓存 - 改完务必执行
nginx -t && systemctl reload nginx,光改配置不重载等于没动
验证是否真进了框架:用/index.php/route/test打头阵
别急着翻路由代码。先在浏览器访问http://yourdomain.com/index.php/route/test(确保这个路径没定义任何路由)。
如果看到ThinkPHP调试页提示「找不到路由」,说明框架已接管;如果返回Nginx原生404页面,且响应头里没有X-Powered-By: ThinkPHP,那就停在这里——问题100%出在入口接管环节,往下查路由文件、缓存、环境变量全是白费。
- curl也能快速验证:
curl -I http://localhost/user/list,看Server和X-Powered-By头是否存在 - 宝塔等面板用户:选了“ThinkPHP”伪静态模板后,一定要打开生成的配置文件,确认规则真实写入,不是只点了个下拉菜单就完事
- 本地能跑、线上404?优先怀疑Linux大小写敏感——
/User/List和/user/list在Windows下可能都通,Linux上就是两个世界
php think route:list为空?说明route/app.php根本没执行
命令行执行php think route:list,输出为空或没你写的/user/profile?这不是语法问题,是文件压根没被加载。
TP8默认自动require app/route.php,但如果你删了它、改名了、或者里面只写了<?php return [];,那等于没注册任何路由。
- 在
app/route.php第一行加die('route loaded');,刷新任意URL,没输出就说明该文件被跳过 - 检查
config/app.php中'url_route_on' => true是否被.env里的APP_URL_ROUTE_ON=false覆盖 - 多应用模式下,路由文件应在
app/应用名/route/app.php,而不是app/route/app.php;同时确认config/app.php的app_map已声明该应用 - 清掉
runtime/route/整个目录——APP_DEBUG=false时路由会被缓存,改了文件也不生效
开启url_route_must后/static/logo.png也404?那是你没放行静态资源
'url_route_must' => true会让ThinkPHP拦截一切请求,只放行显式定义的路由。静态资源路径默认不在白名单里,所以/static/logo.png也会被当成“未定义路由”直接404。
别用Route::alias()或中间件绕,最稳的是用Route::rule()显式放行后缀:
Route::rule(':path^.*\.(js|css|png|jpg|gif|svg|woff2|ttf)$', 'static/:path', 'GET', ['ext' => '']);
注意['ext' => '']这个参数,它防止框架自动补.html后缀;同时检查Nginx有没有冲突的location ~* \.(js|css|png)$规则——它会绕过PHP直接返回,导致ThinkPHP的放行规则失效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











