根据参数值 Yii 重写路由

Rewriting route depending of parameter value Yii

我在 Yii 中有几条规则允许我重写一些路由,其中​​每个路由都将作为 get 参数传递给操作。

'<department>' => 'products/index',
'<department>/<category>' => 'products/index',

我想明确地写一个规则,根据参数值将 url 更改为我想要的任何值

例如,现在我有一个这样的 URL www.mysite.com/Books+%26+Pencils因为这条规则被改写了'<department>' => 'products/index',没问题

我想将 URL 更改为 www.mysite.com/books-pencils ,如果有人知道如何编写比较 deparment 属性值然后将其重写为任何内容的规则我要。

谢谢

首先,如果你想改变一个URL,你应该做一个重定向(在这种情况下301). To implement this logic you can use custom URL rule class

Url 管理员配置:

'rules' => array(
    // custom url rule class
    array(
        'class' => 'application.components.MyUrlRule',
    ),
)

我的Url规则class:

class MyUrlRule extends CBaseUrlRule
{
    public function createUrl($manager,$route,$params,$ampersand)
    {
        // Logic used to create url.
        // If you do not create urls using Yii::app()->createUrl() in your app,
        // you can leave it empty.
    }

    public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
    {
        // modify url
        $pathInfoCleaned = strtolower(preg_replace('+%26+', '-', $pathInfo));

        // redirect if needed
        if ($pathInfo !== $pathInfoCleaned) {
            $request->redirect($pathInfoCleaned, true, 301);
        }

        // parse params from url
        $params = explode('/', $pathInfo);
        if (isset($params[0])) {
            $_GET['department'] = $params[0];
            if (isset($params[1])) {
                $_GET['category'] = $params[1];
            }
        }

        return 'products/index';
    }
}

您可以使用自定义 class 来处理您的特殊要求。 我用过这样的东西,从数据库中获取我的自定义 URLs:

 'urlManager'=>array(
            'rules'=>array(
                array(
                    'class' => 'application.components.UrlRule',
                ),
            ),
        ),

然后你创建你的 custo class 类似于:

<?php

Yii::import("CBaseRule");

class UrlRule extends CBaseUrlRule
{
    public function createUrl($manager,$route,$params,$ampersand)
    {
        // check for my special case of URL route, if not found, then return the unchaged route
        preg_match("/^(.+)\/(.+)$/", $route, $r);
        if(!is_array($r) or !isset($r[1]) or !isset($r[2])) {
            return $route;
        }

        // handle your own route request, and create your url
        $url = 'my-own-url/some-thing';

        // check for any params, which i also want to add
        $urlParams = $manager->createPathInfo($params,"=","&");

        $return = trim($url,'/');
        $return.= $urlParams ? "?" . $urlParams : "";

        return $return;
    }

    public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
    {

        // handle my special url request
        $controller = '....';
        $action = '.....';

        // return the controller/action that should be used     
        return lcfirst($controller)."/".$action;
    }
}

我不知道这是否是您想要的,但至少在这个 class 中您可以根据 URL 的要求做任何您需要的事情。 如果你愿意,例如喜欢用 301 重定向到 1 URL 来重定向很多类似的 URL,你可以在 parseUrl 函数

中想到这样的东西
// check my route and params, and if I need to redirect
$request->redirect('/your/new/url/?params=bla',true,'301');