Yii2 漂亮的 URL:用斜线自动转换所有内容(包括所有参数)

Posted

技术标签:

【中文标题】Yii2 漂亮的 URL:用斜线自动转换所有内容(包括所有参数)【英文标题】:Yii2 pretty URL: automatically convert everything with slashes (including all parameters) 【发布时间】:2016-11-02 03:04:56 【问题描述】:

我正在使用 Yii2,我想使用带有路由的 urlManager 将所有非字母和非数字字符转换为斜杠。我已经看了很多已经被问到的问题(#1、#2、#3、#4),但没有人解决它,因为它们要么显示有点相似,但不是我想要的或不工作的完全是我。

我有简单的 urlManager 规则:

//...
'urlManager' => [
    'class' => 'yii\web\UrlManager',
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => array(
        '<controller:\w+>/<id:\d+>' => '<controller>/view',
        '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
        '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
    ),
],

.htaccess(也很简单):

RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
# Otherwise forward it to index.php
RewriteRule . index.php

就我而言,我丑陋的网址是这样的 (SiteController -&gt; public function actionTestRouter()):

localhost/frontend/web/index.php?r=site%2Ftest-router&ident=10&token=ADB&module=P120

使用我上面写的规则,我得到了更好的结果(因为它删除了index.php?r= 并将%2F 转换为/):

localhost/frontend/web/site/test-router?ident=10&token=ADB&module=P120

我想得到什么:

localhost/frontend/web/site/test-router/ident/10/token/ADB/module/P120

我对规则的几次尝试是:

'test-route/<ident:\d+>/<token:\w+>/<module:\w+>' => 'test-route' // 1
'<controller:\w+>/<action:\w+>/<ident:\d+>/<token:\w+>/<module:\w+>' => '<controller>/<action>' // 2
'<controller:\w+>/<action:\w+>/<slug:[a-zA-Z0-9_-]+>/' => '<controller>/<action>/<slug>' // 3 (not even sure what slug does here

如果规则适用于任何参数和值,不管它们的名称和值如何,那也太好了。

【问题讨论】:

非常感谢您的提问。这就是 Yii 1 默认设置为 urlManager 设置 urlFormat='Path' 的原因,Yii 2 在这方面退了一步,我看不出有什么问题有了它,我已经花了很多时间来弄清楚它。 Yii 1 的逻辑直接在类CUrlManager -&gt; parsePathInfo ($pathInfo) 方法中。所以在 Yii 2 中,我们必须通过自己的实现或以某种方式从 Yii1 重用来克服 有趣的相关问题,但对于 Yii 1 ,虽然可能与通配符重复/乘法运算符相同的方式可以类似地完成 - ***.com/a/20429218/3419535 或类似用法 yii 2 食谱但仅用于乘法单个参数的值 - github.com/samdark/yii2-cookbook/blob/master/book/… 【参考方案1】:

你的第二次尝试

'<controller:[\w\-]+>/<action:[\w\-]+>/<ident:\d+>/<token:\w+>/<module:\w+>' => '<controller>/<action>' // 2

将采用/创建网址

localhost/frontend/web/site/test-router/10/ADB/P120

在 url 中没有参数名称,这些参数将仅按此顺序使用,并且它们的列表是固定的,如您所见

如果你想在 url 中添加他们的名字(出于 estetic 或 seo 的目的,比如你的问题):

'<controller:[\w\-]+>/<action:[\w\-]+>/ident/<ident:\d+>/token/<token:\w+>/module/<module:\w+>' => '<controller>/<action>',  // 2

这些路由的 url 创建将是相同的:

echo Url::to(['site/test-router', 'ident' => 100, 'module' => 100, 'token' => 100]);

如果你想解析这个参数列表的各种长度,你可以像这样使用 smth:

'<controller:[\w\-]+>/<action:[\w\-]+>/<params:[a-zA-Z0-9_\-\/]+>' => '<controller>/<action>'

或只为一条路线指定:

'site/test-route/<params:[a-zA-Z0-9_\-\/]+>' => 'site/test-route'

所以在行动中你会得到参数params:Yii::$app-&gt;request-&gt;get('params'); 用正则表达式解析它。

【讨论】:

感谢您的回答。但是我收到了这个错误:preg_match(): Compilation failed: range out of order in character class at offset 66 在尝试最后一个或倒数第二个选项时。 :// 啊,因为 5.2 减号也应该被转义。答案已编辑。 我还是不明白。 :/ 我尝试了您的编辑并输入了 localhost/frontend/web/site/test-router/ident/10/token/ADB/module/P120(直接输入 URL),但我收到了 404 错误。 这是因为您在路由中的操作包含减号test-route。因此,您应该使用掩码&lt;action:[\w\-]+&gt;,而不是掩码&lt;action:\w+&gt;。答案已编辑。 我明白了。谢谢,我明天试试。 :)

以上是关于Yii2 漂亮的 URL:用斜线自动转换所有内容(包括所有参数)的主要内容,如果未能解决你的问题,请参考以下文章

标量数据

对网址中的斜线/进行urlencode的定义在哪

尾部斜线:是或否? [复制]

在 YII2 中使用自动注销,需要在再次登录后将用户重定向到用户在自动注销之前的相同 URL

tips for Flask

tengine 末尾反斜线问题