CakePHP 友好的 seo 网址

Posted

技术标签:

【中文标题】CakePHP 友好的 seo 网址【英文标题】:CakePHP friendly seo url 【发布时间】:2014-01-14 04:52:04 【问题描述】:

我想让我的 url 对 seo 友好。 www.example.com/posts/view/1 更改为 www.example.pl/:slug-:id。一切正常,但可能是我在路由方面做错了,因为在分页器中点击 url 后,url 是正确的,看起来像 www.example.pl/:slug-:id ,但出现错误

"The requested address 'www.example.pl/:slug-:id' was not found on this server."

我不知道怎么了。这是我的代码:

Router::connect(
    '/:slug-:id',
    array(
        'controller' => 'posts', 
        'action' => 'view'
    ),
    array(
        'pass' => array('slug' , 'id'),
        'id' => '[0-9]+'
    )
);

在分页器视图中:

echo $this->html->link($ad['Post']['title'], array(
    'controller' => 'posts',
    'action' => 'view',
    'slug' => Inflector::slug($post['Post']['title'],'-'),
    'id'=>$post['Post']['id'])
);

我解决了这个问题。

【问题讨论】:

【参考方案1】:

它太简单了,我会给你一个我项目中的例子.. 在你的 routes.php

Router::connect(
    '/:slug-:id',
    array('controller'=>'posts','action'=>'view'),
    array('pass'=>array('slug','id'),'slug'=>'[a-zA-Z0-9 -]+','id'=>'[0-9]+')
);

views 中的链接应该是 .

$this->Html->link(__('link desu'),array('controller'=>'posts','action'=>'view','id'=>$post['Post']['id'],'slug'=>$post['Post']['slug']));

和你的 PostsController.php

public function view($slug,$id)
    $this->Post->id = $id;
    // ....

快速提示:尝试在您的 PostModel 中创建一个数组以避免每次都在您的视图中创建它。 示例:

Post.php

class Post extends AppModel
    // ....
        public function afterFind($results,$primary = false)
        foreach ($results as $key => $value) 
            if(isset($value[$this->alias]['id']))
                $results[$key][$this->alias]['url'] = array(
                                 'controller'=>'posts',
                                 'action'=>'view',
                                 'id'=>$results[$key][$this->alias]['id'],
                                 'slug'=>$results[$key][$this->alias]['slug']
                            );  
            
            // ....
        
        return $results;
    

所以你可以像这样在你的视图中调用它

$this->Html->link(__('link desu'),$post['Post']['url']);

【讨论】:

+1 虽然“快速提示”会分散实际答案的注意力。 怎么来的,它只是为了避免每次你想得到你的网址时创建那些大数组(有时) 记住你在回答一个问题:超过一半的答案与问题无关 - 现在知道问题(参见作者的回答),唯一真正解决问题的行(单数,1)是这个:public function view($slug,$id). 我明白了。只是想用这个有用的提示给我的答案加分,无论如何谢谢:)【参考方案2】:

这可能是路由上的正则表达式有问题。您的 slug 包含连字符 -,您也可以使用它来分隔 slug 和 id。即:

example.com/my-slug-has-hyphens-1

正则表达式不够聪明,无法知道“最后一个”连字符将 slug 与 id 分开。

要测试这是否是问题所在,请尝试使用类似 '/:slug__:id', 这样的路由,看看它是否有效。

【讨论】:

这是一个合理的猜测,但这不是贪婪的正则表达式的工作方式——没有限制,slug 只是字符串'my-slug-has-hyphens'。我建议您在回答之前尝试您的建议。【参考方案3】:

我解决了这个问题。在帖子控制器中,我的视图功能是错误的。这是正确的:

function view($id = null, $slug = null) 
$this->Post->id = $this->params['post'];
$this->set('post', $this->Post->read());

【讨论】:

+1 用于回答您自己的问题。请注意,代码没有错,只是与路由定义不匹配。【参考方案4】:

通行证对订单敏感

问题中路线如下:

Router::connect(
    '/:slug-:id',
    array(
        'controller' => 'posts', 
        'action' => 'view'
    ),
    array(
        'pass' => array('slug' , 'id'), # <-
        'id' => '[0-9]+'
    )
);

这意味着 post 函数将收到:

public function view($slug, $id)

如已编辑的问题所示,代码期望 id 是第一个参数。最简单的解决方案就是按照预期的顺序指定传递的参数:

...
        'pass' => array('id', 'slug'), # <-

【讨论】:

【参考方案5】:
Router::connect(
    '/:slug/:id',
    array(
        'controller' => 'posts', 
        'action' => 'view'
    ),
    array(
        'pass' => array('slug' , 'id'),
        'id' => '[0-9]+'
    )
);

以上代码将创建正确的链接为 www.example.com/posts/view/title/1

echo $this->Html->link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', Inflector::slug($post['Post']['title'],'-'),$post['Post']['id']));

【讨论】:

-1 因为这会更改问题以匹配答案 - 它不回答问题

以上是关于CakePHP 友好的 seo 网址的主要内容,如果未能解决你的问题,请参考以下文章

如果给定的操作不存在,则定义 Cakephp 路由以调用特定的控制器

PHP Cakephp - 获取当前的基本网址(包含域名)

在 MVC 中保存相关数据(cakephp)

CakePHP 3.0 IIS web.config

CakePHP:格式错误的 URL

在 CakePHP 上使用域作为“前缀”