RewriteRouter and Zend_Config play together
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).

July 18th, 2006 at 10:37 pm
[…] Nick Lo (author of the now infamous Mr Dizzy story on getters/setters in constructors) brings us another new tutorial for working with the Zend Framework, getting the RewriteRouter and Zend_Config to play nicely together.[...]
July 18th, 2006 at 11:49 pm
Are there any perfomance hits compared to using mod_rewrite or simply in general.
July 19th, 2006 at 4:09 am
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.
July 19th, 2006 at 9:09 am
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.
November 15th, 2006 at 9:03 pm
At this point in time, this method is no longer working due to a change made in version 0.2.0 where the behaviour of handling routes has changed. The following error is generated when attempting to use Zend_Controller_RewriteRouter:
Fatal error: Argument 2 passed to Zend_Controller_RewriteRouter::addRoute() must be an object of class Zend_Controller_Router_Route_Interface …
The details of this error are explained here:
http://framework.zend.com/issues/browse/ZF-239
The fix version states 0.6.0, so I am going to download the latest snapshot and see what comes of it. If anyone knows of a method that can be used as a workaround, I’d be happy to hear from you.
Best Regards, Dave
November 15th, 2006 at 9:12 pm
As stated aboce, I gave the current snapshot a lick and discoverd that the issue hasn’t been addressed yet. We’ll continue to wait unti 0.6.0 I suppose.
November 19th, 2006 at 9:02 pm
Hi Dave,
Zend_Config has been refactored so all you need now is…
I’ve not actually tested this myself just yet, but the info comes from its developer Rob Allen:
Zend Framework Community Forum
November 19th, 2006 at 9:45 pm
Agh, next time I’ll try not to reply late at night! My answer to Dave above is not the solution to his issue. I should admit I started playing with the ini version of the config files…
…and my route config files look like…
…so I’ve not used the array config for a while. I am interested to find out how to sort this issue out and will post it when I find a solution.
May 11th, 2007 at 11:36 am
Hi,
(sorry for my poor english writing. I did try me best, but…) This is very helpfull. I try and fix my probleme based on this article. But now I’m working on a more complexe website and it doesn’t work. As per your example (ingredients.com.au/articles/cooking/), your structure is:
:controller/:action
applications controllers articl esControllers.php
My structure is
:module/:controller/:action
applications module1 controllers articlesControllers.php models views module2 controllers otherControllers.php models views
for example I have this url: http://www.domaine.com/module2/other/listarticle. In my controller otherController.php, action listarticleAction(). Now, I would like to create the following url ( http://www.domaine.com/listarticle) that will be redirect to http://www.domaine.com/module2/other/listarticle.
As per Zend documentation, I’ve add :
$route = new Zend_Controller_Router_Route_Static( ‘listarticle’, array(‘module’ => ‘module2′, controller’ => ‘other’, ‘action’ => ‘listarticle’) ); $router->addRoute(‘listarticle’, $route);
But the only answer I received from the controller is «Invalid controller specified (listarticle)»… and I don’t know what to do :-(
I know is more like a question than a comment, but hey, I’m so desperate!
May 16th, 2007 at 9:03 pm
Hi Hugo, this post is now getting close to a year old and since that time a lot has changed in the Zend Framework. Although I could answer your question you’ll undoubtedly have more so the best suggestion I’d give to anyone is to visit the mailing list archives:
Zend Framework Mailing List Archives
And better still join the relevant mailing lists:
Zend Framework Mailing Lists
Sorry if that seems like a lazy response but you’re likely not the only visitor coming here with problems so I’m hoping this can be a more general answer for all of you.
December 27th, 2007 at 5:04 pm
hi,
i have one default module and one more module module_1 ,i have one parameter extra in url for langauge like site.com/module/languageparameter/controller/action i defiend it in index.php(bootstarp file) like this
now when i move form some page to another in default module only than in place of module it integrates default for eg:
((site.com/default/languageparameter/controller/action))
and i do not want this in my url when i am traversing in my default module,
i want my url be like this ((site.com/languageparameter/controller/action))
can anybody help me regarding this issue.
thanx in advance