伪静态配置后路由404主因是nginx未将请求转发至public/index.php:必须配置try_files $uri $uri/ /public/index.php?$query_string,确保运行目录设为/public、path_info正确传递且script_filename路径无误。

伪静态配置后路由404,90%不是路由写错了,而是请求压根没进 ThinkPHP —— Nginx 没把 /user/list 这类请求转发给 public/index.php,直接返回了原生 404。
为什么 /index.php/user/list 能通,但 /user/list 404?
这是最明确的伪静态失效信号。说明 PHP 和框架本身没问题,但 Web 服务器没做重写转发。
-
/能打开 →public/index.php可执行,PHP 环境正常 -
/index.php/user/list能通 → 路由定义、控制器、PATH_INFO 解析逻辑大概率没问题 -
/user/list404 → 请求被 Nginx 拦截,去文件系统找这个路径,没找到就甩 404,public/index.php根本没运行 - 用
curl -I http://localhost/user/list看响应头:若没有X-Powered-By: ThinkPHP,基本可锁定是 Nginx 配置问题
Nginx 配置必须检查的三处硬性条件
缺一不可,漏掉任意一个都会导致内页 404。尤其注意宝塔用户:「伪静态 → ThinkPHP」模板默认生成的是 TP5 规则,对 TP6 无效。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
location /块里必须有转发逻辑:try_files $uri $uri/ /public/index.php?$query_string;(TP6 入口在public/,不是项目根目录) -
fastcgi_param PATH_INFO $fastcgi_path_info;必须存在,且放在location ~ \.php$块内;不能漏,也不能写错位置 -
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;不能写成$request_filename,后者在重写后可能指向错误物理路径 - 站点「运行目录」必须设为
/public(宝塔:网站设置 → 运行目录;否则所有 rewrite 路径都偏移一级)
PATH_INFO 为空导致路由解析失败
即使请求进了 public/index.php,如果 $_SERVER['PATH_INFO'] 是空的,ThinkPHP 就无法提取 /user/list 这段路径,所有控制器都匹配不上。
- 在
public/index.php开头加一行:var_dump($_SERVER['PATH_INFO']); die();,访问/user/list,应输出/user/list,不是空字符串或/index.php - 确认 Nginx 配置中有:
fastcgi_split_path_info ^(.+\.php)(/.*)$;(配合$fastcgi_path_info使用) - 检查
location ~ \.php$块中是否误保留了宝塔默认的try_files $uri =404;—— 这行会提前截断请求,必须注释掉 - 宝塔用户特别注意:
/www/server/nginx/conf/php/74.conf里常含冲突行,直接注释掉整行# try_files $uri =404;
开了 url_route_must 后静态资源也 404 怎么办
启用 'url_route_must' => true 后,ThinkPHP 会拦截一切请求,只放行显式定义的路由。/static/css/app.css 这类路径默认不在白名单里,直接 404。
- 在
route/app.php最顶部加放行规则:Route::rule(':path^.*\.(js|css|png|jpg|gif|svg|woff2|ttf)$', 'static/:path', 'GET', ['ext' => '']); - 别指望框架自动识别静态文件,强制路由模式下,一切都要显式声明
- 该规则必须放在所有
Route::get()、Route::group()之前,否则会被后续路由覆盖
最容易被忽略的是:PATH_INFO 是否真实传递成功,以及宝塔「运行目录」是否真的设成了 /public。很多问题表面看是配置漏项,实则是这两处没对齐,导致整个 rewrite 链路偏移一级。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










