RewriteRouter and Zend_Config play together

July 18, 2006

by — Posted in Zend Framework

While getting the hang of the Zend_Controller_RewriteRouter, which is now included in Zend Framework 0.1.5, I was adding the routes in my index.php (bootstrap) file and wondered if there was any way of storing them elsewhere. It is possible to loop over Zend_Controller_RewriteRouter::addRoutes() but the method I will describe here is based on some recent updates to Zend_Controller_RewriteRouter by its author Michael Minicki.

The point of RewriteRouter is to map urls, like ingredients.com.au/recipe/tomato_sambal, to whatever controller, action and parameters needed without having to use external (and often painful!) methods like mod_rewrite.

For the sake of this article I’ll use a relatively simple URL…

ingredients.com.au/articles/cooking/

First setup some routes in a config file “routes.php”. Note that this does require the latest version of the RewriteRouter which needs to be checked out from the subversion repository

$config['routes']['articles'] = 
new Zend_Controller_Router_Route('articles/:category', 
array('category' => 'all', 
       'controller' => 'articles', 
       'action'      => 'index' ), 
       array('category' => '[a-z_]+') );

This establishes a route called “articles” that will respond to any url of the form “/articles/whatever” with the colon in :category indicating that it is an url variable that can be recovered through Zend_Controller_Action::_getParam( ‘category’ ). The controller and action indexes make the action “indexAction” in the controller file “ArticlesController.php” the final target. To cover cases where there is no category specified the default setting “all” is given. For extra assurance :category has to be a string containing only lower case letters and underscores as indicated by the final requirements array.

Next load them into the bootstrap file using Zend_Config_Array:

$routes = new Zend_Config( 
        Zend_Config_Array::load( 
       '../application/configuration/routes.php', 'routes' ) );

Then create the RewriteRouter object and pass it the $routes…

$router = new Zend_Controller_RewriteRouter;
$router->addRoutes( $routes );

All that is needed now is to pass the $router to the front controller…

$controller = Zend_Controller_Front::getInstance();
$controller->setRouter( $router );

That’s it, now the routes are nicely stored outside of the bootstrap file and with the rest of the domain files.

Further Reading

Aside from the manual pages mentioned I can’t close without pointing to an actual recipe for tomato sambal !!

Endnote

I should also mention that it’s well worth getting involved with the development of the framework even if you can only do so in a small way. After a relatively short discussion via the issue tracker about having some means to load routes in one hit, Michael Minicki had implemented one (thanks Michael).

  • Pingback: PHPDeveloper.org()

  • brian

    Are there any perfomance hits compared to using mod_rewrite or simply in general.

  • Good article. My reservation with your method of putting routes into the config file is that then you have to include the Zend_Controller_RewriteRouter file in your config file. I prefer to not to include code in my config file.

    Even aside from my personal preferences, this method can’t be used with XML or INI config files.

  • Thanks for the comments…

    Brian – Honestly, no idea right now. I’m actually testing/working these routes into underwater.com.au so my current concern is whether I can match/improve that sites current urls rather than performance. Besides if you read my Mr Dizzy post you’ll notice that I’ve discovered a few more serious optimisations. In the future I’d certainly be looking at it but that would also include looking at how I structure a site with regards to how many custom urls I would actually need.

    Duane – Yeah, I agree with you there. It’s not perfect at the moment and I’m glad you mention that. On the other hand perhaps my error is to refer to this as a “config file” since the parameters required by RewriteRouter are a fiddly collection of arrays and I’m not sure INI would have enough depth to cope with them. XML and YAML should be able to but they would likely end up more complex that the original arrays. Part of my reason for publishing this was in fact to open up discussion/thought on methods of storing the routes.