3

我一直在 Stackoverflow 和 YII 论坛上搜索,有很多答案,但对我没有帮助......

这是我的情况。

我有一个名为:proj的控制器和一个名为view的动作。它得到:id(int),name(字符串)。

所需的名称有时会带有特殊字符,例如: [ +,!#$%^&*- ]

因此,当我运行createUrl()函数时,它会返回不那么友好的 url。

例如: http ://www.qa-mysite.com/proj/1029/Conservation+of+the+Vermont+Salt+Pan+System%2C+Hermanus%2C+South+Africa 。

id = 1029 名称 = 佛蒙特盐锅系统保护,赫曼努斯,南非。

我希望结果是: http ://www.qa-mysite.com/proj/1029/conservation-of-the-vermont-salt-pan-system-hermanus-south-Africa

所以实际上我需要去除特殊字符并将空格之间的分隔符更改为“-”而不是“+”。

我当前的 curlManager 配置是:

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName'=>false,
            'appendParams' => true,
            'rules'=>array(
            //array('proj/view/<name:\w+>', 'pattern'=>'proj/<id:\d+>'),
                //'<controller:\w+>/<id:\d+>'=>'<controller>/view',
                'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        )

创建网址示例:

$this->createUrl('proj/view', array('id' => $data->id, 'name' => $data->name));

更改 url 后,我需要将旧的301 重定向到新的 seo 友好的 url。

注意:我不能硬编码 str_replace。

非常感谢您的帮助:]

4

3 回答 3

3

首先,PeterM 的回答很好,这是一种很好的方法。

我以不同的方式做到了。

我创建了一个名为“ TextHelper ”的助手,它有一个静态函数:

class TextHelper{
    public static function cleanText($text=""){
        $text = preg_replace('/[^A-Z0-9]+/i', '-', $text);
        $text = strtolower(trim($text, '-'));

        return $text;
    }
}

并将createUrl()更改为由cleanText ()清理,如下所示:

$this->createUrl('proj/view', array('id' => $proj->id, 'name' => TextHelper::getSlug($proj->name)));

最后,我的config/main.php

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName'=>false,
            'appendParams' => true,
            'rules'=>array(
                'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        )

该解决方案为我完成了工作。希望对于其他需要面对这个问题的开发人员来说,这将是一个简单有效的解决方案。

于 2013-09-19T08:39:44.590 回答
3

CUrlManager通过子类化和 ovveride创建您自己的 url 管理器createUrl,例如:

class MyUrlManager extends CUrlManager {
    public function createUrl($route,$params=array(),$ampersand='&') {
        if($route == 'proj/view' && isset($params['name'])) {
            $params['name'] = processYourParamFunction($params['name']);
        }
        return parent::createUrl($route,$params,$ampersand);
    }
}

然后修改您的配置以使用此类:

...
'urlManager' => [
    'class' => 'MyUrlManager'
...
]

这是 Yii 的一大特色,自然控制反转:)

对于问题的第二部分:

在您查看操作时,如果您检测到不需要的字符,只需使用 createurl 重定向到新 url。只要确保你没有点击重定向循环。

更新:

要使用 301 重定向,只需将重定向代码第三个参数传递给重定向调用:

$this->redirect('route', true, 301);

边注:

使用规范将搜索引擎指向正确的 url

于 2013-09-18T11:49:19.950 回答
0

该解决方案为我完成了工作。希望对于其他需要面对这个问题的开发人员来说,这将是一个简单有效的解决方案。

'urlManager'=>array(
                'urlFormat'=>'path',
                'showScriptName'=>false,
                'appendParams' => true,
                'rules'=>array(
                    'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                    '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
                ),
            )
于 2013-12-27T10:36:30.183 回答