我知道视图和控制器不应该共享逻辑..但我怎么能这样做?

时间:2010-12-07 17:53:25

标签: php model-view-controller cakephp

我有一个名为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; ?>

在没有代码重复的情况下处理此问题的最佳方法是什么?

3 个答案:

答案 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作为模型数据的一部分存储在数据库中,因此你甚至可以查询它。