Yii框架 404错误怎么解_Yii框架路由失效修复方法【技巧】
Yii框架404错误本质是路由未匹配控制器,而非文件不存在。常见原因包括Nginxtry_files缺少$args、PHP-FPM缺失REQUEST_URI参数、视图目录放置错误或urlManager规则覆盖默认映射。检查enablePrettyUrl配置、控制器命名及缓存可快速定位问题。
先说一个核心判断:Yii 框架的 404 错误,本质上是路由没匹配到控制器,而不是文件真的丢了。这话听起来有点绕,但搞清楚这一点,能帮你省掉大量无效的排查时间。

绝大多数 Yii 404 都不是 Nginx 返回的“页面不存在”,而是 Yii 自己抛出的 NotFoundHttpException。这意味着请求其实已经顺利进了 index.php 的大门,问题出在后面——UrlManager 没匹配到任何路由规则,或者对应的控制器、动作压根不存在。
怎么快速验证呢?很简单,临时把 urlManager 配置里的 enablePrettyUrl => true 注释掉,用原始的 ?r=product/index 去访问。如果页面能正常打开,那问题就锁定在美化 URL 这条链路上;如果还是 404,那多半是控制器名、动作名写错了,或者对应的文件没有生成。
Nginx try_files 配置漏掉 $args 就会丢参数
很多人在这里栽跟头:try_files $uri $uri/ /index.php?$args; 这行代码必须完整,尤其是末尾的 $args,一个都不能少。漏掉它的话,/product/123 被转发给 /index.php 时,原始路径信息就丢失了,Yii 只能看到空的 REQUEST_URI 或者默认值,UrlManager 根本没法解析出 product/123 对应的是哪个控制器和动作。
- 错误写法:
try_files $uri $uri/ /index.php;(没有$args) - 正确写法:
try_files $uri $uri/ /index.php?$args; - 如果你用的是 pathInfo 模式(默认),Nginx 不需要额外重写,靠
$args把完整路径传过去就行 - 如果你用的是 get 模式(比如
?r=product/view&id=123),那try_files末尾要改成/index.php?,不过不推荐这么做
PHP-FPM 缺 fastcgi_param REQUEST_URI 就等于没传路由
即使 Nginx 正确转发了请求,如果 PHP-FPM 没收到真实的 REQUEST_URI,Yii 依然拿不到美化后的路径。这种情况常见于只配了 location ~ \.php$ 却漏掉了关键参数。
必须确保该 location 块内包含以下参数:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param REQUEST_URI $request_uri;
缺 REQUEST_URI:Yii 看到的是 /index.php,而不是 /product/123,所有美化规则全部失效;
缺 SCRIPT_FILENAME:PHP 会报 No input file specified.;
PATH_INFO 在某些 urlManager 配置下也是必须的,尤其当启用了 usePathInfo => true 时。
Gii 生成 CRUD 后 404,90% 是视图目录放错了
Gii 生成的 ProductController 默认期望视图文件在 views/product/ 下。如果手一抖,把文件拖进了 views/layouts/product/ 或者 views/site/product/,Yii 就会因为找不到 index.php 直接抛 404,连控制器都进不去。
- 检查实际路径:
views/product/index.php是否存在(不是views/layouts/product/) - 控制器类名必须是
ProductController,且文件名是ProductController.php,大小写敏感 - 动作方法名必须是
actionIndex()、actionView($id)这种格式,不能写成index()或view() - 清除缓存:
php yii cache/flush-all,否则旧的路由规则可能还在生效
最隐蔽的一点:urlManager 的 rules 数组里如果写了自定义规则,并且正则写得太宽泛(比如 '),反而会覆盖默认的控制器/动作映射逻辑,导致 Gii 生成的标准 URL 失效——这种问题往往要关掉美化 URL 才能发现。


































