404主因是请求未进入thinkphp路由系统,而非路由定义错误;需优先排查web服务器重写配置、入口文件接管、伪静态规则生效情况及路由注册位置与时机。

404 不是路由写错了,而是请求压根没进到 ThinkPHP 的路由系统里——绝大多数情况,问题出在 Web 服务器配置或框架入口接管失败上。
为什么 /user/list 报 404,但 /index.php/user/list 能访问
这是最典型的伪静态未生效信号。ThinkPHP 默认靠重写规则把所有非静态请求转发给 index.php,如果没转过去,Nginx 或 Apache 就直接返回 404,根本不会触发框架的路由逻辑。
- Apache 用户:确认项目根目录有
.htaccess,且对应<directory></directory>块中AllowOverride All已开启 - Nginx 用户:检查
server块内是否有location / { try_files $uri $uri/ /index.php?$query_string; };注意不是/index.php?s=$1(TP6 更倾向 QUERY_STRING 模式) - 宝塔等面板用户:选了“ThinkPHP”伪静态模板后,务必打开生成的配置文件,确认规则已真实写入并执行了
nginx -t && systemctl reload nginx - 用
curl -I http://localhost/user/list看响应头,如果返回Server: nginx且无X-Powered-By: ThinkPHP,说明请求没进 PHP 层
php think route:list 不显示你写的路由
命令输出为空或缺路由,代表框架压根没加载到你的定义。这不是语法错,是注册时机或位置错了。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 确保路由写在
route/route.php(全局路由)或route/app.php(应用级路由),而不是控制器、模型或中间件里 - 别在条件语句或闭包里动态调用
Route::get(),比如if (env('APP_ENV') === 'dev') { Route::get(...); }—— 环境变量可能未就绪 - 检查命名空间:用了
Route::group(['prefix' => 'api'], function () { ... }),但访问的是/user/list,前缀不匹配就不会进该组 - 清掉
runtime/cache/下所有文件再试,缓存会固化旧路由结构
开启强制路由后 /static/logo.png 也 404
'url_route_must' => true 会让 ThinkPHP 拦截一切请求,只放行显式定义的路由。静态资源路径默认不在白名单里,所以被当成“未定义路由”直接 404。
- 推荐方案:用
Route::rule()显式放行后缀,例如:Route::rule(':path^.*\.(js|css|png|jpg|gif|svg|woff2|ttf)$', 'static/:path', 'GET', ['ext' => '']);其中['ext' => '']关键,防止框架自动补.html - 别名方式(
Route::alias('static', 'static'))要放在route/app.php最顶部,否则可能被后续Route::get()规则覆盖 - 同时检查 Nginx 是否有冲突的
location ~* \.(js|css|png)$规则 —— 它会绕过 PHP 直接返回 404,导致路由配置失效 - 验证时看 Network 面板:状态码 200 是基础,还要确认响应头含
X-Powered-By: ThinkPHP,才算真正走通了路由放行逻辑
Linux 上大小写敏感导致的 404
Windows 开发时 /User/List 和 /user/list 都能访问,一上 Linux 全挂,是因为 ThinkPHP 默认区分 URL 大小写,而 Windows 文件系统不区分。
- 前端发请求的路径(如 AJAX URL)、路由定义里的字符串、控制器类名三者必须完全一致,包括首字母大小写
- 不要依赖
'url_convert' => true来自动转小写 —— 它会掩盖路径拼写混乱的问题,上线后更难排查 - 更稳的做法:Nginx 层加 301 重定向,或统一要求前端全小写,后端路由也全小写定义
- 用
php think route:list输出的路径做比对基准,它显示的就是框架实际注册的原始路径
真正卡住人的往往不是某条规则怎么写,而是你不确定这个请求到底被谁处理了:是 Nginx 直接拒了?还是进了 PHP 但路由没注册?还是注册了但大小写不匹配?先用 curl -I 和 php think route:list 锁定层级,再逐层往下查。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










