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