ThinkPHP去index.php后404是伪静态未生效,需依次验证:Web服务器重写规则(Nginx用$query_string、Apache开启AllowOverride)、路由文件位置与内容(app/route/app.php)、app_route和url_route_on为true、大小写一致、排除url_route_must拦截静态资源。

ThinkPHP路由配置后访问URL总是返回404,但加/index.php又能正常打开,说明请求根本没进框架——这不是代码写错了,而是从Web服务器到框架启动的整条链路中某处断开了,必须按顺序逐层验证。
第一步:确认请求是否抵达ThinkPHP入口
在浏览器中直接访问带index.php的完整路径,例如http://yourdomain.com/index.php/user/profile。
能打开页面,说明PHP环境、入口文件、控制器方法都正常;打不开,问题出在PHP未运行或public目录未正确设为网站根目录,先停在这里排查基础环境。
如果带index.php可访问,但去掉后报404,【说明伪静态规则完全没生效,后续所有路由配置检查都无效】,立刻跳转第二步。
立即学习“PHP免费学习笔记(深入)”;
第二步:检查Web服务器重写配置
方法一(Nginx):
打开站点配置文件,在server块内找到location /段,确认包含且仅包含这一行核心规则:try_files $uri $uri/ /index.php?$query_string;。
⚠️特别注意:$request_filename或/index.php?s=$1是ThinkPHP 5旧写法,TP6/8必须用$query_string模式,否则GET参数丢失、路由匹配失败。
改完执行nginx -t && systemctl reload nginx,再测试。
方法二(Apache):
确认项目public/.htaccess文件真实存在,内容为标准ThinkPHP重写规则(含RewriteEngine On和RewriteRule ^(.*)$ index.php [L])。
进入虚拟主机配置,找到对应<directory></directory>块,确保里面有AllowOverride All且未被AllowOverride None覆盖。
最后运行apachectl -M | grep rewrite,输出含rewrite_module才表示模块已启用。
第三步:验证路由文件是否被加载
① 运行命令:php think route:list。
② 如果输出为空,或列表里根本没有你写的路由,说明路由文件根本没执行。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
③ 检查路径:单应用项目必须写在app/route/app.php,不是config/route.php或route/route.php;多应用(如admin)必须写在app/admin/route/app.php。
④ 打开该文件,确认第一行是use think\facade\Route;,且文件末尾有实际调用(如Route::get('test', 'Index/test');),不能只有return [];或全是注释。
⑤ 清空runtime/cache/下所有文件,缓存会固化旧结构,不清理新路由永不生效。
第四步:核对关键开关与大小写
打开config/app.php,确认这两项为布尔值true:
'app_route' => true,
'url_route_on' => true,
⚠️字符串"true"或数字1都不行,必须是PHP原生布尔true。
Linux服务器上严格区分大小写:前端请求/User/List,而路由定义是Route::get('/user/list', ...),就会404;Windows开发时不会暴露此问题,上线即崩。
检查所有前端URL拼写、控制器类名(UserController.php首字母必须大写)、方法名,全部统一为小写路径+帕斯卡命名控制器。
第五步:排除强制路由与静态资源拦截
如果开启了'url_route_must' => true,所有请求(包括/static/logo.png)都必须命中显式路由,否则直接404。
此时需在app/route/app.php顶部添加放行规则:
Route::rule(':path^.*\.(js|css|png|jpg|gif|svg|woff2|ttf)$', 'static/:path', 'GET', ['ext' => '']);
【其中['ext' => '']不可省略,否则框架会自动补.html后缀导致匹配失败】。
同时检查Nginx配置里是否有location ~* \.(js|css|png)$这类直接返回静态文件的规则——它会绕过PHP,导致ThinkPHP路由完全失效。


















