Yii2美化URL:自动转换所有带斜杠的内容(包括所有参数)

8
我正在使用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

在我的情况下,我的丑陋的URL是这样的(SiteController -> 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 -> parsePathInfo ($pathInfo) 方法中实现。因此,在 Yii 2 中,我们必须通过自己的实现或从 Yii 1 中进行重用来解决问题。 - FantomX1
有趣的相关问题,但是针对Yii 1,尽管通配符重复/乘法运算符可能以类似的方式实现相同的功能-https://stackoverflow.com/a/20429218/3419535,或者在yii 2 cookbook中进行类似的使用,但仅适用于单个参数的多个值-https://github.com/samdark/yii2-cookbook/blob/master/book/urls-variable-number-of-parameters.md。 - FantomX1
1个回答

7
你的第二次尝试
'<controller:[\w\-]+>/<action:[\w\-]+>/<ident:\d+>/<token:\w+>/<module:\w+>' => '<controller>/<action>' // 2

将会获取/创建URLs

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

没有参数名称的URL,这些参数仅按照固定顺序使用,并且它们的列表如您所见。

如果您想在URL中添加它们的名称(例如美观或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]);

如果你想解析这个参数列表的不同长度,可以使用以下方法:
'<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->request->get('params');使用正则表达式进行解析。

谢谢你的回答。但是当我尝试最后一个或倒数第二个选项时,出现了这个错误:preg_match(): Compilation failed: range out of order in character class at offset 66。:/ - Gynteniuxas
我还是没搞对。:/ 我尝试了你的编辑并输入了 localhost/frontend/web/site/test-router/ident/10/token/ADB/module/P120(直接在URL中输入),但我得到了 404 错误。 - Gynteniuxas
这是因为您的路由中的操作包含减号“test-route”。因此,您应该使用掩码<action:[\w\-]+>而不是<action:\w+>。答案已编辑。 - user1852788
我知道了。谢谢,我明天会尝试的。 :) - Gynteniuxas
看起来你在浏览器中输入了错误的网址。你的网址应该是这样的:http://localhost/site/test-route/ident/10/token/ADB/module/P120 - user1852788
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接