伪静态失效导致404,主因是请求未进入ThinkPHP入口文件public/index.php;/user/list 404而/index.php/user/list正常即为典型表现,需检查服务器配置是否正确转发非物理路径请求。

伪静态失效导致 404,绝大多数情况不是路由写错了,而是请求压根没进到 ThinkPHP 的入口文件——public/index.php 根本没被执行。先确认这点,再往下调。
为什么 /user/list 404,但 /index.php/user/list 能正常?
这是最典型的伪静态未生效信号。Nginx 或 Apache 没把非物理路径的请求转发给 index.php,而是直接当作“找不到文件”返回了 Web 服务器原生 404(不带 TP6 黄色调试页)。
- Apache 用户:检查
public/.htaccess是否存在、权限为644,且虚拟主机配置中AllowOverride All已开启 - Nginx 用户:必须在
location /块内配置try_files $uri $uri/ /index.php?$query_string;,不能只靠宝塔下拉选“ThinkPHP”——那个规则默认适配 TP5,对 TP6 的public/入口结构大概率失效 - 宝塔用户特别注意:
网站目录 → 运行目录必须设为/public;否则你贴的 Nginx 规则里写的/index.php实际对应的是服务器上不存在的路径 - 如果项目部署在子目录(如
https://example.com/tp6/),try_files的 fallback 必须改成/tp6/index.php?$query_string,否则重写会失败
php think route:list 不显示自定义路由,说明什么?
命令无输出或只显示默认路由,代表路由文件根本没被加载,或加载时机错误。这不是 404 的表象,而是深层原因。
- 检查路由是否定义在
app/route/app.php(单应用)或app/index/route/app.php(多应用),而不是写在控制器、中间件或钩子里——那些地方执行时路由系统尚未初始化 - 确认
config/app.php中'url_route_on' => true,且没被.env里的环境变量覆盖(比如APP_ENV=testing时某些配置可能被跳过) -
APP_DEBUG = false时,TP6 会缓存路由到runtime/route/;改完路由后务必清空该目录,否则新规则永不生效 - 用了
Route::import()?确保传入的路径是相对app/route/的,且文件存在、语法无 fatal error(比如漏了分号导致整个文件 parse 失败)
多语言路由(如 /zh/user/list)404 怎么定位?
多语言前缀本质是路径的一部分,它和普通路由一样参与匹配,但容易因顺序、作用域或大小写被忽略。
立即学习“PHP免费学习笔记(深入)”;
- 确保语言前缀路由注册在所有具体路由之前,例如:
Route::group(['prefix' => 'zh'], function () { Route::get('/user/list', 'User::list'); });—— 如果Route::get('/user/list', ...)写在前面,/zh/user/list就永远不会匹配到这个 group - 检查域名绑定:
Route::domain('zh.example.com')和路径前缀是两套机制,别混用;若用了Route::domain(),请求必须命中对应域名,否则整个 group 被跳过 - Linux 服务器上,
/ZH/user/list和/zh/user/list是不同路径;前端生成 URL 时必须和路由定义完全一致(包括大小写),ThinkPHP 默认区分路径大小写 - 避免在多语言路由里嵌套通配路由(如
Route::any('[:all]', ...)),它会吞掉所有后续规则,导致/en/user/list也进不了语言 group
Nginx 下 $_SERVER['PATH_INFO'] 为空,但 URL 看起来能访问
这会导致 TP6 的 PathInfo 模式路由无法解析控制器和方法,表现为 /index.php/user/list 也 404,而 /index.php?s=/user/list 可以——说明 rewrite 成功了,但 PHP 没收到 pathinfo。
- 检查 Nginx 的 PHP 处理块,必须包含这两行(缺一不可):
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;fastcgi_param PATH_INFO $fastcgi_path_info; - 确保
location ~ \.php$块和location /块逻辑连贯;如果它们是孤立的,rewrite 后的请求可能匹配不到 PHP 块 - 宝塔用户重点看
74.conf(位于/www/server/nginx/conf/php/):里面那句try_files $uri =404;会与 pathinfo 冲突,必须注释掉 - 不用
rewrite ^(.*)$ /index.php?s=$1 last;这种旧写法——它把整个路径塞进$_GET['s'],破坏原生$_GET,且无法支持 POST 数据完整传递
真正卡住人的往往不是路由怎么写,而是 Nginx 配置里某一行被注释了、某个路径少写了 /public、或者 runtime 缓存没清——这些细节不报错,只安静地让一切 404。



















