需配置web.php中log组件支持trace级别、urlmanager启用prettyurl和strictparsing,并在log targets中指定yii\web\urlmanager分类;还需清空runtime缓存。

开启 Yii2 路由匹配日志需要改哪些配置
Yii2 默认不记录 URL 规则匹配过程,得手动打开路由调试开关,并确保日志组件能捕获 yii\web\UrlManager 的日志级别。关键不是加个参数就完事,而是要让日志通道真正收到匹配失败/成功的 trace 级别消息。
- 在
config/web.php的components里确认log组件已启用,且targets中至少有一个支持trace级别(比如FileTarget) - 给
urlManager加上'enablePrettyUrl' => true和'showScriptName' => false(否则部分规则不会触发匹配逻辑) - 必须设置
'enableStrictParsing' => true,否则即使规则不匹配也会 fallback 到默认路由,看不到“为什么没进这条 rule” - 在
log的targets中添加过滤器:指定'categories' => ['yii\web\UrlManager'],并把'levels' => ['trace', 'info']
怎么看到具体哪条 rule 被命中或跳过
光开日志还不够——Yii2 的 UrlManager 只在 parseRequest() 和 createUrl() 内部打 trace 日志,内容很简略,比如 "Matched route: 'site/index'" 或 "No matching URL rule"。要定位到具体 rule,得自己加点钩子。
- 重写
UrlManager::parseRequest(),在循环遍历$this->rules时,对每条 rule 手动加\Yii::trace("Trying rule: " . get_class($rule), 'yii\web\UrlManager') - 或者临时在
vendor/yiisoft/yii2/web/UrlManager.php的第 280 行左右(foreach ($this->rules as $rule)循环内)插入一行\Yii::debug($rule->pattern, 'yii\web\UrlManager') - 注意:生产环境千万别留这种硬编码调试,只用于本地排查;用完记得删掉或注释掉
- 日志文件里会按执行顺序出现多条
Trying rule: ...,最后一条Matched route就是最终命中的那条
常见匹配失败却无日志的原因
不是日志开了就一定能看到匹配过程。很多情况下你改了配置,但日志里还是空的,大概率卡在这几个地方:
-
urlManager配置写在console.php里了——Web 请求根本不用 console 的配置,必须放在web.php或被它引入的配置中 - 请求走的是 index-test.php 或其他入口脚本,而该脚本加载的配置没包含 log + urlManager 调试项
- PHP 错误抑制符
@被用在了Yii::createObject()或new UrlManager()前,导致异常吞掉,trace 日志也一并丢失 - Apache/Nginx 没配好 rewrite 规则,请求压根没进 Yii 入口(比如访问
/index.php/site/index是 OK 的,但/site/index404),此时UrlManager根本没机会运行
用 yii\debug 工具栏看路由匹配更直观
比翻日志文件快得多:只要启用了 yii\debug\Module,每次页面加载后点顶部工具栏的 “Router” 标签页,就能看到本次请求经过的所有规则、是否匹配、生成的 route 和参数。
- 确保
debug模块只在dev环境启用,且'allowedIPs' => ['127.0.0.1', '::1']已设好 - 如果 “Router” 标签页为空,说明请求没走到 Yii 的完整生命周期(比如被中间件提前 return,或 controller 构造函数抛了异常)
- 它显示的是最终生效的 rule,不展示跳过的规则——想看“为什么没选 A 而选了 B”,还是得靠上面说的 trace 日志+手动插桩
最常被忽略的一点:修改 urlManager 配置后,必须清空 runtimes/cache/ 下的 urlManager* 缓存文件,否则旧规则还在内存里跑,日志里看到的匹配路径和你刚写的 rule 对不上。











