PS: 首先明确一下,请确保你的框架版本 >=2.0.12,老版本在URL生成逻辑中存在一些bug。
如果你的项目不方便直接更新框架版本,可以单独更新 vendor/yiisoft/yii2/web/UrlRule.php 文件。
详细的可以查看 `yii\web\UrlRule` 类的源码
@see github.com/yiisoft/yii2/issues/10970
另外网上大部分问答,似乎都是在重复官方文档中的配置说明,不解决实际问题。所以重新整理还是有必要的,也希望各位看官能有所收获。
//... 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'cache' => YII_DEBUG ? false : 'cache', 'suffix' => '.html', 'rules' => [ 'pattern' => 'route', //写法1 [ 'class' => 'yii\web\UrlRule',//非必要 'pattern' => '', 'route' => '', 'suffix' => '.do',// 优先级高 //...其它 ], //写法2 //... ], ],
//方式1 //适合一些比较简单的路由规则设置,但是如果出现可选参数,可以采用 配置多条规则的方式解决。 //例如,规则如下 'site/test-<a:\w+>-<b:\w+>' => 'site/index', 'site/test-<b:\w+>' => 'site/index', //测试 echo Url::to(['site/index', 'b'=>'bvalue']); //输出 /site/test-bvalue.html //... //其它同理
//假设我定义3条规则 'site/test-<a:\w+>-<b:\w+>' => 'site/index', 'site/test-<b:\w+>' => 'site/index', 'site/test-<a:\w+>' => 'site/index', //那么在我访问 /site/test-value.html 的时候 // 这个 value 是a的值还是b的值呢? //为了避免这种问题, 就可能需要把规则修改为如下配置 'site/test-a<a:\w+>-b<b:\w+>' => 'site/index', 'site/test-b<b:\w+>' => 'site/index', 'site/test-a<a:\w+>' => 'site/index',
//沿用 上述例子, 注意 这时候 我们只定义下面一个路由规则 [ 'pattern' => 'site/test-<a:\w+>-<b:\w+>', 'route' => 'site/index', ], //先看看 echo Url::to(['site/index','b' => 'bvalue']); //输出 /site/index.html?b=bvalue //变成了 带问号的 get传参形式, 这当然不是我们想要的。 //调整rule配置,如下 [ 'pattern' => 'site/test-<a:\w+>-<b:\w+>', 'route' => 'site/index', 'defaults' => [ //默认值 'a' => '', //只能是 空字符串 ], ], //新增了 参数默认值的配置 //重新测试 输出 /site/test--bvalue.html //到这边其实已经满足了我们的基础需求, 但还是不完善的
//rule 样例配置 [ 'class' => UrlRuleWeb::class, 'pattern' => 'site/test-<aa:\d+>-<bb:\d+>-<cc:\d+>', 'route' => 'site/index', 'suffix' => '.do', //自定义后缀 可选配置 'defaults' => [ 'aa' => 2, 'bb' => '0', ], ], //测试 echo Url::to(['site/index', 'cc' => 3]); //输出 /site/test-2-0-3.do