CakePHP 3:生成缩短的url(规范)

时间:2015-09-23 07:45:29

标签: php .htaccess cakephp redirect

我尝试防止重复内容。 我的帖子原始网址是这样的:

  

domain.com/post/52-quick-brown-fox-jumps-over-lazy-dog

我想生成一个缩短的网址,并使用它们分享,例如,twitter

  

domain.com/p/52 ---->重定向到--->原始网址

怎么办呢?通过htaccess 301重定向?通过CakePHP路由?

谢谢!

2 个答案:

答案 0 :(得分:3)

重定向本身应为301(永久移动),因此所有指向短网址的链接都会映射到Google索引中的长网址。

Router类有一个自己的redirect方法。您基本上复制了实际路线,将connect替换为redirect并更改网址模式以匹配您的短网址:

$routes->redirect('/p/:id', ['controller' => 'Posts', 'action' => 'display'], [
    'pass' => ['id'],
    'status' => 301,
    'persist' => true
]);
$routes->connect('/post/:id-:slug', ['controller' => 'Posts', 'action' => 'display'], [
    'pass' => ['id', 'slug']
]);

唯一的缺点:据我所知,您将无法从Router类生成短网址,因为它将始终从传递的参数生成长网址。您必须从id手动生成它们。

确保Controller检查是否存在正确的slug,如果不是,则执行重定向到正确的url。您可以使用Controllers redirect() method

public function display($id, $slug = null) {
    $post = $this->Posts->findById($id);
    if($post) {
        if($post->slug !== $slug) {
            return $this->redirect('/post/' . urlencode($id . '-' . $slug), 301);
        }
        //Other stuff
    } else {
        $this->Flash->error('The post was not found.');
        return $this->redirect('/posts');
    }
}

如果您想避免双重定向,可能需要使用connect代替redirect(感谢ndm代表该评论):

$routes->connect('/p/:id', ['controller' => 'Posts', 'action' => 'display'], [
    'pass' => ['id'],
    'status' => 301
]);
$routes->connect('/post/:id-:slug', ['controller' => 'Posts', 'action' => 'display'], [
    'pass' => ['id', 'slug']
]);

如果slug错误或缺席,Controller仍应重定向到正确的URL。

答案 1 :(得分:1)

<强> SOLUTION:

配置/ routes.php文件

//slug url format, in my case .com/p/id
$routes->connect(
    '/p/:id',
    ['controller' => 'Posts', 'action' => 'view'],
    [
        'pass' => ['id', 'slug'],
        'id' => '[0-9]+',
        'status' => 301
    ]
);

PostsController.php

// If slug is null, redirect to the full post url
public function view($id=null, $slug=null)
{
    $post = $this->Posts->get($id);
    if( is_null($slug) ) {
        $this->redirect('/post/'.$post->id.'-'.$post->slug, 301);
    }
    $this->set(compact('post'));
}