2010-10-22 6 views
0

J'utilise un routeur personnalisé pour activer les pages comme:Comment créer un routeur personnalisé dans 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 

J'ai aussi la table de base de données « catégories » dans laquelle toutes les catégories sont stockées. Par exemple, supposons que les catégories suivantes sont actuellement stockées dans ma base de données:

- html 
- css 
- js 
- php 

Cela signifie, les pages suivantes sont réunies:

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

Mais lorsque vous visitez une page avec un categoryname qui ne figure pas dans la base de données, comme:

  • mytutorialsite.com/category/foo

Vous devriez obtenir une page 404 n'existe pas message.

Comment puis-je y parvenir?

Répondre

1

Je pense que vous voulez dire par nom de catégorie comme action sur votre route le: nom de catégorie doit être utilisé comme une action? Il y a deux méthodes que vous pouvez utiliser. Tout d'abord, vous ajoutez uniquement les routes vers le routeur où les catégories existent. Lorsque la catégorie/foo est demandée, le routeur ne reconnaîtra pas l'itinéraire et lancera l'erreur 404. La deuxième option consiste à attraper toutes les routes de catégorie/* et à vérifier si la catégorie existe dans votre action.

Pour la première option, ajoutez un plugin frontController avec une fonction routeStartup. Dans ce crochet, vous pouvez faire:

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); 
    } 
} 

L'autre méthode est plus simple pour la route. Dans votre application.ini:

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

Maintenant, toutes les demandes de la catégorie/CHOSE passera au module par défaut, le contrôleur de la catégorie. Le répartiteur vérifie si l'action SOMETHING existe. Quand c'est le cas, il exécute l'action. Dans le cas contraire, une Zend_Controller_Action_Exception ("l'action n'existe pas") est throw.

Donc, en bref, les deux méthodes fonctionnent. Avec le premier, vous obtenez plus de contrôle. La seconde est plus simple mais quand par ex. il existe un editAction, un addAction ou un removeAction dans le categoryController, ils peuvent aussi être déclenchés (attention à cette méthode).

PS.Bien sûr, la fonction routeStartup devrait avoir un mécanisme de mise en cache pour empêcher une requête de base de données sur chaque requête.

+0

Merci, c'était très utile !! –

+0

Il n'y a qu'un seul problème avec le plugin frontcontroller. Maintenant, chaque nom $ category-> a sa propre action dans le contrôleur. Si vous voulez que tous les noms de catégories utilisent la même catégorie categoryAction, il suffit de changer 'action' => 'categoryname' ne fonctionne pas. –

+0

C'est exact. Si vous voulez router l'url vers la même action, c'est encore plus simple (voir ma supposition en haut de ma réponse). La route est simple: "category /: category" et ajoutez une action à cette route ("categoryName"). Ensuite, dans le categorynameAction, le paramètre "category" est disponible via $ this -> _ getParam ("category"). –

Questions connexes