在UrlManager中捕获用户定义的URL

时间:2017-03-01 20:31:57

标签: php yii yii2

我可以让用户为他们的某些项目定义URL,例如:

http://x.com/mynewobject

mynewobject将由用户在表单中定义,我需要能够在UrlManager中说出数学,但也匹配其他所有内容。

问题是UrlManager中的默认规则会尝试捕获mynewobject控制器并在不能执行时抛出404。

制作UrlManager用户定义网址的方法是什么?

1 个答案:

答案 0 :(得分:0)

我发现这样做的最好方法是在不手动声明您的网址的情况下,实际上是仔细查看Yii 2文档。

它实际上显示了用户生成的网址http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html#creating-rules的一个很好的示例,我用它来完成我的任务。

我使用的配置是:

'urlManagerFrontend' => [
    'class' => 'yii\web\UrlManager',
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'cache' => null,
    'baseUrl' => '/',
    'rules' => [

        [
            'class' => 'common\components\ObjectUrlRule',
            'pattern' => '<slug:.*>',
            'route' => 'site/index'
        ],

        '<controller:[\w-]+>/<id:\d+>'=>'<controller>/view',
        '<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>'=>'<controller>/<action>',
        '<controller:[\w-]+>/<action:[\w-]+>'=>'<controller>/<action>',
        // your rules go here
    ]
],

规则类:

<?php

namespace common\components;

use Yii;
use yii\web\UrlRule;
use common\models\ObjectUrl;

class ObjectUrlRule extends UrlRule
{
    public function parseRequest($manager, $request)
    {
        $pathInfo = trim($request->getPathInfo());
        if(!$pathInfo){
            return false;
        }

        $controller = Yii::$app->createController($pathInfo);
        if($controller){
            return false;
        }

        $objectUrl = ObjectUrl::find()->where(['url' => $pathInfo])->one();
        if(!$objectUrl){
            return false;
        }

        return $objectUrl->getUrl($pathInfo);
    }
}

其中ObjectUrl是包含用户生成的URL地图的模型(表)。

这个类的优点还在于它不会运行数据库调用,除非控制器不存在并且有一个pathinfo。