我一直在搜索Stackoverflow和YII论坛,有很多答案, 这对我没有帮助......
这是我的情况。
我有一个叫做 proj 的控制器和一个名为 view 的动作。 它得到: id (int),名称(字符串)。
所需的名称有时带有特殊字符,例如:[ +,!#$%^& * - ]
因此,当我运行 createUrl()函数时,它返回的不是那么友好的URL。
id = 1029 name =保护佛蒙特州SaltPan系统,赫曼努斯,南非。
我希望结果如下: 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>',
),
)
CreateUrl示例:
$this->createUrl('proj/view', array('id' => $data->id, 'name' => $data->name));
在更改网址后,我需要将旧网址的 301重定向发送到新的友好网址。
注意:我不能做硬编码的str_replace。
非常感谢您的帮助:]
答案 0 :(得分:3)
通过子类化CUrlManager
和ovveride 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功能之一,自然inversion of control:)
问题的第二部分:
在您查看操作中,如果您检测到不需要的字符,只需使用createurl重定向到新网址。只要确保你没有点击重定向循环。
<强>更新强>
要使用301重定向,只需将第三个参数传递给重定向代码以重定向调用:
$this->redirect('route', true, 301);
旁注:
使用cannonical将搜索引擎指向正确的网址
答案 1 :(得分:3)
首先,PeterM的答案很好,这是一个不错的方法。
我以不同的方式做到了。
我创建了一个名为&#34; TextHelper &#34;的帮助程序,其中包含一个静态函数:
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>',
),
)
该解决方案为我完成了这项工作。 希望对于需要面对这个问题的其他开发人员来说,这将是简单而有效的解决方案。
答案 2 :(得分: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>',
),
)