必须同时启用enablePrettyUrl为true、showScriptName为false,并配置Web服务器重写规则将请求转发至index.php,三者缺一不可,否则URL美化完全不生效。

urlManager 不是“单独开启”的组件,它默认就存在;真正要做的,是启用它的美化功能(enablePrettyUrl),并配齐依赖条件。否则即使写了 rules,也完全不生效。
必须同时满足的三个硬性条件
缺一不可,顺序也不能错:
-
enablePrettyUrl设为true—— 这是开关,不设就等于没开 -
showScriptName设为false—— 否则生成的 URL 仍带index.php,前端看起来还是丑的 - Web 服务器(Apache/Nginx)已配置好重写规则,把所有非静态资源请求转发给
index.php—— 否则美化后的 URL 直接 404
config/main.php 里怎么写才有效
只改 components 下的 urlManager 配置块。常见错误是漏掉 enablePrettyUrl => true,或把它和 rules 分开写成两个数组项。
正确示例(精简版):
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
'' => 'site/index',
'about' => 'site/about',
'post/<id:\d+>' => 'post/view',
],
],
注意:<id:\d+> 中的 < 和 > 是字面量,不能省略;正则部分必须用英文冒号分隔,不能写成 id\d+ 或 id=[0-9]+。
Apache 和 Nginx 的重写配置别踩坑
Web 服务器没配好,urlManager 再怎么配都是白搭。重点不是“有没有”,而是“是否精准拦截非资源请求”:
- Apache:项目根目录(通常是
web/)下必须有.htaccess,且mod_rewrite已启用;内容不能只写RewriteRule ^(.*)$ index.php,要加RewriteCond排除真实文件和目录 - Nginx:不能用
if (!-e $request_filename)做判断——这是过时写法,某些版本会跳过try_files导致循环或 500;必须用try_files $uri $uri/ /index.php?$args;
为什么开了 enablePrettyUrl 还是跳 404?
最常被忽略的点:你可能只改了 frontend/config/main.php,但实际访问的是 backend 或 console 环境;或者在多模块项目中,urlManager 配置放在了 common/config/main.php 却没被正确加载。
验证方法:临时加一行 var_dump(Yii::$app->urlManager->enablePrettyUrl); die(); 在任意控制器 action 开头,看输出是不是 bool(true)。不是,说明配置根本没进到运行时实例里。


















