Howto: Utiliser Zend_Controller_RewriteRouter avec Zend_Config
By Geoffrey on Tuesday 31 October 2006, 20:26 - Coding - Permalink
Comme je le disais plus bas, le Zend Framework Preview 0.2.0 est dans les bacs ! Cette nouvelle mouture apporte son lot de nouveautés, et nous allons nous pencher sur une des plus interressantes: le RewriteRouter. Le RewriteRouter est un routeur pour le composant MVC du Zend Framework qui va nous permettre de configurer nos URL comme dans Ruby on Rails, c'est à dire (en gros), via un fichier de configuration, et c'est là que Zend_Config entre en jeu.
Mettre en place le routeur
C'est bien beau tout ça, mais pour l'utiliser, il faut déjà en informer le controlleur. Pour cela, rien de plus simple, on utilise la méthode addRouter:
$router = new Zend_Controller_RewriteRouter; $controller = Zend_Controller_Front::getInstance(); $controller->setRouter($router);
Le RewriteRouter est pré-configuré avec deux routes qui permettent d'assurer la compatibilité descendante avec l'ancien routeur, donc jusque là, tout va bien.
Déclarer les routes
Nous utiliserons un fichier de configuration dédié aux routes, que nous appellerons sobrement routes.ini, et que nous placerons dans app/, à coté de son compagnon config.ini. Ce fichier de configuration contiendra une unique section [routes], qui contiendra à son tour les multiples définitions de routes que nous souhaitons y caser. Une route se compose de 5 éléments principaux:
- L'identifiant de la route. C'est un identifiant interne utilisé par le
RewriteRouter, - l'URL de la route, c'est ce qui permet au routeur de reconnaitre la route à utiliser,
- les valeurs par défauts des variables,
- les requirements de la route, qui permettent de déterminer si une route est bien formée ou non.
Sans plus attendre, un petit exemple: la route qui pourrait permettre d'accéder à un billet dans dotclear 2:
post.route = post/:year/:month/:day/:title post.reqs.year = "\d+" post.reqs.month = "\d+" post.reqs.day = "\d+" post.reqs.title = "[a-zA-Z0-9_:-]"+ post.defaults.controller = post post.defaults.action = view post.defaults.title =
Elle pourrait seulement, car en fait, la regexp du title est trop restrictive (une URL peut contenir d'autres caractères que ceux là), et de plus, les URL stockées par dotclear 2 en base de données comprennent tout ce qui se trouve après post/ (par exemple le champs post_url de ce billet contient: 2006/10/31/Howto:-Utiliser-Zend_Controller_RewriteRouter-avec-Zend_Config).
Cela étant dit, la route que nous venons de décrire s'appliquera aux URLs suivantes:
/post/2006/30/10/ZendFramework/post/42/2006/56/Foobar/post/2006/30/10/- etc.
Mais pas à:
/post/2006/Foobar/post/Foobar/2006/30/01- etc.
On note donc d'ores et déjà:
- que la validation des composants d'une route se fait par expression régulière
- qu'on peut ommettre le dernier composant d'une route si il possède une valeur par défaut (récursivement)
- qu'on ne peut pas modifier l'ordre des composants d'une route
- qu'on doit spécifier manuellement le nom du controlleur et de l'action à utiliser
- et c'est déjà pas mal.
Décortiquons maintenant une URL: /post/2006/30/10/ZendFramework. Le routeur va diviser cette URL ainsi:
- Controller:
post(d'après les defaults) - Action:
view(d'après les defaults) - Paramètres:
year: 2006,month: 30,day: 10,title: ZendFramework (d'après l'URL)
Les paramètres ainsi détectés seront disponibles via la méthode $this->_getParam($name); a l'intérieur du controlleur.
Dernier point de ce chapitre, une déclaration de route peut comporter deux variables spéciales: :controller et :action, qui servent respectivement à détecter le controller et l'action à utiliser dans l'url. Par exemple, la route builtin compat chargé d'assurer la compatibilité descendante se déclare ainsi:
compat.route = :controller/:action compat.defaults.controller = index compat.defaults.action = index
Assembler le tout
Dernière étape, transférer directement toutes ces déclarations dans le Routeur: n'y allons pas par quatre chemin:
$router->addConfig(new Zend_Config_Ini('/path/to/routes.ini', null), 'routes');
C'est aussi simple que ça. Ce qui nous donne, en prenant en compte le morceau de code du début de l'article:
$router = new Zend_Controller_RewriteRouter; $router->addConfig(new Zend_Config_Ini($routes_path, null), 'routes'); $controller = Zend_Controller_Front::getInstance(); $controller->setRouter($router);
And voilà. Je ne saurais que vous conseiller la lecture du manuel pour plus d'informations (sachant qu'en fait, addRoute attend en deuxième argument une instance de Zend_Controller_Router_Route, mais qui s'instancie avec les paramètres qu'ils passent à addRoute, petite coquille du manuel :p).
Comments
Petit précision pour la méthode $router->addConfig(...)
http://framework.zend.com/issues/br...