2010-10-22 5 views
0

Я использую пользовательский маршрутизатор для того, чтобы страницы, как:Как создать настраиваемый маршрутизатор в 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

Но при посещении страницы с CategoryName, которые не перечислены в базе данных, как:

  • mytutorialsite.com/category/foo

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

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

ответ

1

Я думаю, что вы имеете в виду с именем категории как действие на вашем маршруте: 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. Когда это произойдет, он выполняет действие. Когда нет, исключение Zend_Controller_Action_Exception («действие не существует») - это throw.

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

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

+0

Спасибо, это было очень полезно! –

+0

Есть только одна проблема с плагином frontcontroller. Теперь каждое имя $ category-> имеет свое собственное действие в контроллере. Если вы хотите, чтобы все имена категорий использовали один и тот же тип categoryAction, просто изменение «action» => «categoryname» не работает. –

+0

Это правильно. Если вы хотите перенаправить URL-адрес на все те же действия, это еще проще (см. Мое предположение в верхней части моего ответа). Маршрут прост: «category /: category» и добавьте действие к этому маршруту («categoryName»). Затем в категории nameAction параметр «категория» доступен через $ this -> _ getParam («category»). –