You need to enable JavaScript to run this app. Yii2路由规则匹配失败返回404 未校验后续模块路由问题求解
优惠活动
大模型
产品
解决方案
定价
更多

Yii2路由规则匹配失败返回404 未校验后续模块路由问题求解

问题根因

Yii2路由规则按从上到下顺序匹配,<controller>这类泛化占位符规则只会校验URL格式是否匹配,不会提前校验对应控制器是否存在。如果把泛化controller规则放在模块规则前面,只要URL格式符合controller规则,就会直接命中,后续解析时发现控制器不存在直接返回404,不会走到后续模块规则。你当前把controller规则全部注释,所以请求http://yii2/post没有对应规则匹配,自然返回404。


解决方案

给泛化controller规则增加matchCallback回调,主动校验对应根控制器是否存在,存在才命中规则,不存在则跳过继续匹配后续模块规则,修改后的完整配置参考如下:

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        'store/upload'=>'store/upload',
        'stores'=>'store/index',
        'comment/send'=>'comment/send',
        ['class' => 'yii\rest\UrlRule', 'controller' => 'Api',  'prefix' => 'api'],
        'api/<id:\d+>'=>'api/view',
        [
            'pattern' => 'users',
            'route' => 'users/index',
            'suffix' => '/',
            'normalizer' => false,
        ],
        // 根控制器通用规则 增加存在性校验
        [
            'pattern' => '<controller>',
            'route' => '<controller>/index',
            'matchCallback' => function ($rule, $request) {
                $controllerName = Yii::$app->request->getPathInfo();
                $controllerClass = 'app\controllers\\' . ucfirst($controllerName) . 'Controller';
                return class_exists($controllerClass);
            }
        ],
        [
            'pattern' => '<controller>/<id:\d+>',
            'route' => '<controller>/view',
            'matchCallback' => function ($rule, $request) {
                $pathParts = explode('/', Yii::$app->request->getPathInfo());
                $controllerName = $pathParts[0];
                $controllerClass = 'app\controllers\\' . ucfirst($controllerName) . 'Controller';
                return class_exists($controllerClass);
            }
        ],
        [
            'pattern' => '<controller>/<action>',
            'route' => '<controller>/<action>',
            'matchCallback' => function ($rule, $request) {
                $pathParts = explode('/', Yii::$app->request->getPathInfo());
                $controllerName = $pathParts[0];
                $controllerClass = 'app\controllers\\' . ucfirst($controllerName) . 'Controller';
                return class_exists($controllerClass);
            }
        ],
        // 模块相关规则放在后面
        '<module>' => '<module>/default/index',
        '<module>/<id:\d+>' => '<module>/default/view',
        '<module>/edit/<id:\d+>' => '<module>/default/edit',
        '<module>/delete/<id:\d+>' => '<module>/default/delete',
        '<module>/<action>' => '<module>/default/<action>',
        '<module>/<controller>' => '<module>/<controller>/index',
        '<module>/<controller>/edit/<id:\d+>' => '<module>/<controller>/edit',
        '<module>/<controller>/delete/<id:\d+>' => '<module>/<controller>/delete',
        '<module>/<controller>/<id:\d+>' => '<module>/<controller>/view',
        '<module>/<controller>/<action>' => '<module>/<controller>/<action>',
    ],
],

如果你的控制器命名空间不是默认的app\controllers,请替换为实际的命名空间路径即可。

内容的提问来源于stack exchange,提问作者temp_name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 05:42:03