Как создать настраиваемый маршрутизатор в Zend-Framework?

Я использую настраиваемый маршрутизатор для включения таких страниц, как:

mytutorialsite.com/category/:categoryname

# added to application.ini resources.router.routes.categorynameOnCategory.route = /category/:categoryname resources.router.routes.categorynameOnCategory.defaults.module = default resources.router.routes.categorynameOnCategory.defaults.controller = category resources.router.routes.categorynameOnCategory.defaults.action = categoryname 

У меня также есть «категории» таблицы базы данных, в которых хранятся все категории. Например, допустим, что в моей базе данных хранятся следующие категории:

 - html - css - js - php 

Это означает, что существуют следующие страницы:

  • mytutorialsite.com/category/html
  • mytutorialsite.com/category/css
  • mytutorialsite.com/category/js
  • mytutorialsite.com/category/php

Но когда вы посещаете страницу с именем категории, не указанным в базе данных, например:

  • mytutorialsite.com/category/foo

Вы должны получить сообщение 404 Страница «Не существует» .

Как мне это достичь?

Я думаю, вы имеете в виду с категорией как действие на вашем маршруте: categoryname должно использоваться как действие? Вы можете использовать два метода. Во-первых, вы добавляете только маршруты к маршрутизатору, где существуют категории. Когда запрашивается категория / foo, маршрутизатор не распознает маршрут и не выдает ошибку 404.

Второй вариант – вы поймаете все маршруты категории / *, а внутри вашего действия вы проверяете, существует ли категория.

Для первого варианта добавьте плагин frontController с функцией routeStartup. В этом крюке вы можете:

 public function routeStartup(Zend_Controller_Request_Abstract $request) { // Get the router $router = Zend_Controller_Front::getInstance()->getRouter(); // Fetch all your categories $category = new Application_Model_Category; $categories = $category->fetchAll(); // Loop and add all individual categories as routes foreach ($categories as $category) { $route = 'category/:' . $category->name; $params = array( 'module' => 'default', 'controller' => 'category', 'action' => $category->name ); $route = new Zend_Controller_Router_Route($route, $params); $router->addRoute($category->name, $route); } } 

Другой метод более прост для маршрута. В вашем приложении application.ini:

 resources.router.routes.category.route = "category/:action" resources.router.routes.category.module = "default" resources.router.routes.category.controller = "category" 

Теперь все запросы из категории / SOMETHING перейдут в модуль по умолчанию, контроллер категории. Диспетчер проверяет, существует ли действие SOMETHING. Когда это произойдет, он выполняет действие. Когда нет, исключение Zend_Controller_Action_Exception («действие не существует») – это throw.

Короче говоря, оба метода работают. С первым вы получите больше контроля. Второй более простой, но когда, например, есть editAction, addAction или removeAction в категорииController, они также могут запускаться (поэтому будьте осторожны с этим методом).

PS. Конечно, функция routeStartup должна иметь механизм кэширования для предотвращения запроса базы данных по каждому запросу.