【问题标题】:How to 301 redirect old URL to new URL in CakePHP 2.x with slug lookup?如何使用 slug 查找在 CakePHP 2.x 中将旧 URL 301 重定向到新 URL?
【发布时间】:2018-02-12 13:22:22
【问题描述】:

我需要像这样重定向 (301) url:

https://website.com/products/view/id

到:

https://website.com/products/product-name-slug

我知道如何使 url 的 slug 版本工作,但我不想完全禁用旧的,而是希望它们 301 重定向到它的 slug 版本。 我不希望它们同时工作,因为它被 Google SEO 视为重复的内容。

我也不想像这样在 routes.php 中为每个产品编写重定向:

Router::redirect( '/product/view/1001', [ 'controller' => 'products', 'action' => 'view', 'product-1001-name-slug' ] );

相反,我宁愿使用动态查找功能来为我做这件事。

如何在 CakePHP 2.x 中做到这一点?

【问题讨论】:

    标签: php cakephp cakephp-2.0


    【解决方案1】:
    • Create a custom route class处理此案
    • 检查 slug 是否存在于新的 slug 字段中
      • 如果是,那就太好了,没什么可做的
      • 如果没有尝试在旧的 slug 字段中查找 slug
        • 如果存在则重定向到新的 slug 并设置 HTTP 状态
        • 如果不存在则返回 false

    【讨论】:

    • 那么你的意思是我可以将 CakeRoute::parse($url) 函数中的参数从 $params['id'] 替换为 $params['slug']?
    • 我可以在 ::redirect 中使用自定义路由类而不是 ::connect 吗?
    【解决方案2】:

    这是@burzum 回答的示例实现:

    在 routes.php 中:

    Router::connect(
        '/product/view/:slug',
        array( 'controller' => 'base_products', 'action' => 'view' ),
        array( 'pass' => array( 'slug' ) )
    );
    Router::connect(
        '/base_products/view/:id',
        [ 'controller' => 'product', 'action' => 'view', 'model' => 'BaseProduct' ],
        [ 'routeClass' => 'IdToSlugRoute' ]
    );
    

    在 app/Routing/Route/IdToSlugRoute.php 中:

    public function parse($url) {
            $params = parent::parse($url);
            if (!$params) {
                return false;
            }
    
            if (!$this->response) {
                $this->response = new CakeResponse();
            }
    
            App::import('Model', $params['model']);
            $Model = new $params['model']();
            $instance = $Model->find('first', array(
                'conditions' => array($params['model'] . '.id' => $params['id']),
                'recursive' => 0
            ));
    
            $slug = getSlug( $instance[$params['model']]['id'], $instance[$params['model']]['name'] );
            $redirect = ['controller' => $params['controller'], 'action' => $params['action'], $slug];
    
            $status = 301;
            $this->response->header(array('Location' => Router::url($redirect, true)));
            $this->response->statusCode($status);
            $this->response->send();
            $this->_stop();
        }
    

    在 app/Controller/BaseProductsController.php 中:

    function view($slug)
        {
            $id = getIdFromSlug($slug);
    
            $product = $this->BaseProduct->find('first', array(
                'conditions' => array('BaseProduct.id' => $id),
                'recursive' => 2
            ));
    
            ...
        }
    

    附加性:

    function getIdFromSlug( $slug ) {
        $pieces = explode( "-", $slug );
    
        return $pieces[0];
    }
    
    function getSlug( $id, $name ) {
        return $id . '-' . Inflector::slug($name, '-');
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-30
      • 2014-11-13
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多