【问题标题】:CakePHP: Can I Promote active router with Router::promote or some other way?CakePHP:我可以使用 Router::promote 或其他方式提升活动路由器吗?
【发布时间】:2013-04-20 06:51:45
【问题描述】:

我有两个或多个路由将指向同一个控制器和动作。这很好,直到我想在页面上使用表单助手或分页等助手。 发生的情况是当前 url 更改为我的 routes.php 文件中首先声明的任何内容。

我看到promote a router with Router::promote 有一种方法,但我不确定是否可以根据当前使用的 url 或路由器来实现它,或者是否有更好的方法来做到这一点。

这是我的router.php 的示例:

Router::connect('/cars-for-sale/results/*', array('controller' => 'listings', 'action' => 'results'));
Router::connect('/new-cars/results/*', array('controller' => 'listings', 'action' => 'results'));
Router::connect('/used-cars/results/*', array('controller' => 'listings', 'action' => 'results'));

例如,假设我在 url domain.com/used-cars/results/ 上使用表单助手或分页助手,放在操作或 href 中的 url 是 domain.com/cars-for-sale/results/

任何帮助或信息将不胜感激。

【问题讨论】:

    标签: php cakephp url-rewriting cakephp-2.0 url-routing


    【解决方案1】:

    路由应该是唯一且可识别的!

    这些路由的问题在于,基本上,您创建了重复的 URL,这不仅会导致 CakePHP 选择正确的路由出现问题,而且 Google 也不喜欢这样;重复的内容会对您的 SEO 排名产生负面影响!

    为了选择正确的 URL(路由),CakePHP 应该能够根据其参数这样做;您当前的路线没有提供任何区分它们的方法。

    你的应用程序也没有!

    所有这些 URL 都将呈现相同的数据;

    /cars-for-sale/results/
    /new-cars/results/
    /used-cars/results/
    

    解决方案 1 - 单独的操作

    如果您的应用程序仅限于这三个类别,最简单的解决方案是创建三个操作,每个类别一个;

    控制器:

    class ListingsController extends AppController
    {
        const CATEGORY_NEW       = 1;
        const CATEGORY_USED      = 2;
        const CATEGORY_FOR_SALE  = 3;
    
        public $uses = array('Car');
    
    
        public function forSaleCars()
        {
            $this->set('cars', $this->Paginator->paginate('Car', array('Car.category_id' => self::CATEGORY_FOR_SALE)));
        }
    
        public function newCars()
        {
            $this->set('cars', $this->Paginator->paginate('Car', array('Car.category_id' => self::CATEGORY_NEW)));
        }
    
        public function usedCars()
        {
            $this->set('cars', $this->Paginator->paginate('Car', array('Car.category_id' => self::CATEGORY_USED)));
        }
    }
    

    Routes.php

    Router::connect(
        '/cars-for-sale/results/*', 
        array('controller' => 'listings', 'action' => 'forSaleCars')
    );
    Router::connect(
        '/new-cars/results/*', 
        array('controller' => 'listings', 'action' => 'newCars')
    );
    Router::connect(
        '/used-cars/results/*', 
        array('controller' => 'listings', 'action' => 'usedCars')
    );
    

    解决方案 2 - 将“类别”作为参数传递

    如果用于“列表”的 URL 列表不固定并会扩展,最好将“过滤器”作为参数传递并将其包含在您的路由中;

    routes.php

    Router::connect(
        '/:category/results/*',
        array(
             'controller' => 'listings',
             'action'     => 'results',
        ),
        array(
    
             // category: lowercase alphanumeric and dashes, but NO leading/trailing dash
             'category'  => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
    
             // Mark category as 'persistent' so that the Html/PaginatorHelper
             // will automatically use the current category to generate links
             'persist'   => array('category'),
    
             // pass the category as parameter for the 'results' action
             'pass'      => array('category'),
        )
    );
    

    阅读Router API

    在您的控制器中:

    class ListingsController extends AppController
    {
        public $uses = array('Car');
    
    
        /**
         * Shows results for the specified category
         *
         * @param string $category
         *
         * @throws NotFoundException
         */
        public function results($category = null)
        {
            $categoryId = $this->Car->Category->field('id', array('name' => $category));
    
            if (!$categoryId) {
                throw new NotFoundException(__('Unknown category'));
            }
    
            $this->set('cars', $this->Paginator->paginate('Car', array('Car.category_id' => $categoryId)));
        }
    }
    

    并且,创建到某个类别的链接;

    $this->Html->link('New Cars', 
        array(
             'controller' => 'listings', 
             'action'     => 'results', 
             'category'   => 'new-cars'
        )
    );
    

    【讨论】:

    • 感谢您的回答 thaJeztah。在收到您的回复之前,我实际上决定将其分解为单独的操作。我只是想过度简化我猜想的事情并消除冗余。但有时为了获得更多功能而重复某些内容更有意义。
    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 2021-02-26
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    相关资源
    最近更新 更多