我有一个名为DesignersController
的控制器,index
方法列出它们,view
方法接受设计器名称作为参数并按名称检索它。
所以/designers
将列出所有设计师,/designers/view/designer-name
将显示该设计师。
现在,如果设计师名称有空格,则需要在URL中进行转义。我有逃避空间和取消空间的逻辑:
private $space_escape_char = '-';
function escapeSpaces($str)
{
return str_replace(" ",$this->space_escape_char,$str);
}
function unescapeSpaces($str)
{
return str_replace($this->space_escape_char," ",$str);
}
现在view
上的Controller
方法需要访问它,所以当它传递了像“Foo-Bar”这样的名字时,它可以将其转换为“Foo Bar”。
index.ctp视图文件也需要访问它,因此当它列出所有设计器时,它可以提供每个设计器的链接,并且能够转义每个名称:
<?php foreach ($designers as $designer): ?>
<div>
<?php
echo $this->Html->link(
$designer['Designer']['name'],
array(
'controller' => 'designers',
'action' => 'view',
escapeSpaces($designer['Designer']['name'])
)
);
?>
</div>
<?php endforeach; ?>
在没有代码重复的情况下处理此问题的最佳方法是什么?
答案 0 :(得分:5)
通常的做法是将实体的主要ID放在URL中,并在关键字/可用性的URL中使用名称/标题(在您的案例中为设计者名称)。
例如
/designers/view/13/designer-name/
控制器只关心13,在数据库中搜索ID 13的设计者。根本不会使用designer-name
。
这是在Stackoverflow上完成的方式。
它还会阻止/ designers / view / john-smith12 /
答案 1 :(得分:3)
如果这是常见现象,我建议在用户数据库条目中存储URL slug。计算一次,然后从那里重新使用它。为什么每次重新计算一些相同的东西?
答案 2 :(得分:3)
你在这里做的是将设计师的名字转换成slu ,,但是要手动。你可以做的是使用行为(如this Sluggable Behavior)自动存储设计师名称的slug。此后,您可以在任何您希望URL安全版本名称的地方引用$designer['Designer']['slug']
。这个slug作为模型数据的一部分存储在数据库中,因此你甚至可以查询它。