Динамическая маршрутизация в CakePHP

#php #cakephp #dynamic #routing

#php #cakephp #динамическая #маршруты

Вопрос:

Я пытаюсь установить динамические маршруты для небольших CMS. Есть ли правильный способ, как это сделать? Я где-то основал это решение, но, честно говоря, я им не удовлетворен. CMS имеют другие типы контента, поэтому определять это для каждой модели мне кажется неправильным.

 $productsModel = ClassRegistry::init('Product');
$products = $productsModel->find('all');    
foreach($products as $product){
  Router::connect('/produkty/:id/'.$product['Product']['url'], array('controller' => 'products', 'action' => 'view',$product['Product']['id']));
} 
  

Спасибо за любую помощь!

Ответ №1:

Не нужно делать ничего сложного 🙂

В routes.php:

 Router::connect('/produkty/*', array('controller'=>'products', 'action'=>'view'));
  

В products_controller.php:

 function view($url = null) {
    $product = $this->Product->find('first', array('conditions'=>array('Product.url' => $url)));
    ...
}
  

Комментарии:

1. Я только начал с CakePHP, поэтому я не понимал, что функции могут иметь другие параметры, а не только ID. Итак, теперь я должен определить уникальную проверку для URL в модели, и это сделано. Спасибо!

2. Я только что столкнулся с одной маленькой проблемой. Это ваше решение отличное, но у меня есть один тип контента под названием mainpage , и у этого действительно специфическая маршрутизация. URL этого типа должен быть сразу после имени домена, например http://cake.dev/contact . Любая помощь с этим? Спасибо

3. Если это всего лишь несколько страниц, я рекомендую просто создать явный маршрут для каждой из них, поскольку это более чистое решение: Router::connect('/contact', array('controller'=>'mainpages', 'action'=>'view', 'contact')); Если у вас их слишком много, вы можете добавить универсальный параметр в конце routes.php передавать все, что не соответствует вашему контроллеру mainpages. Продолжение в следующем комментарии…

4. Router::connect('*', array('controller'=>'mainpages', 'action'=>'view')); С этим связаны две проблемы. Вам нужно будет добавить маршруты для всех ваших других контроллеров действия над общим. Во-вторых, вам нужно будет добавить вызов с ошибкой 404 в mainpages_controller-> view(), если страница не найдена.

5. Я пытался Router::connect('*', array('controller'=>'mainpages', 'action'=>'view')); , но у меня возникла проблема с этим. Я не могу объявлять маршруты статически, потому что администратор сайта всегда может создать новый, поэтому я пока использовал код из моего оригинального поста.

Ответ №2:

Йоп,

Вам не нужно определять маршрут для каждой записи в вашей модели DB. Маршруты — ЭТО динамика. Существует много способов определения маршрутов, но проще всего передавать аргументы в действие по мере их поступления.

routes.php

 Router::connect('/produkty/*', array('controller' => 'products', 'action' => 'view'));
  

products_controller.php

 class ProductsController extends AppController{
    public function view($id){
         //do anything you want with your product id
    }
}
  

Вы также можете использовать именованные аргументы

routes.php

 Router::connect('/produkty/:id/*', array('controller' => 'products', 'action' => 'view'), array('id' => '[0-9] '));
  

products_controller.php

 class ProductsController extends AppController{
    public function view(){
         //named args can be find at $this->params['named']
         $productId = $this->params['named']['id'];
    }
}