If you use Zend Framework you probably used the initRoutes() function in your Initializer.php to create nice URI’s and creating some different routing in your application. To create a customized route for your application you can use the Zend_Controller_Router_Route class from the Zend Framework.
Example code
$route = new Zend_Controller_Router_Route('/your-uri/',array(
'module' => 'default',
'controller' => 'index',
'action' => 'index',
));
Zend_Controller_Front::getInstance()->getRouter()->addRoute('/your-uri/',$route);
If you use this the syntax like above you have to do this for all routes in your application. This makes it not maintainable for programmers. To fix this problem we are going to use a XML file with all routing information.
Example routing XML
<?xml version="1.0" encoding="UTF-8"?>
<nav>
<item name="Home" url="/" isrouter="true" display="true"
controller="index" action="index">
<subitems>
<item name="News" url="/news/" isrouter="true" display="true"
controller="news" action="index">
<subitems>
<item name="Category 1" url="/news/category-1/" isrouter="false"
display="true" controller="news" action="category" />
<item name="Category 2" url="/news/category-3/" isrouter="false"
display="true" controller="news" action="category" />
<item name="Category 3" url="/news/category-3/" isrouter="false"
display="true" controller="news" action="category" />
<item name="Category Routing" url="/news/:category/" isrouter="true"
display="false" controller="news" action="category" />
</subitems>
</item>
<item name="Sport" url="/sport/" isrouter="true" display="true"
controller="sport" action="index">
<subitems>
<item name="Category 1" url="/sport/category-1/" isrouter="false"
display="true" controller="sport" action="category" />
<item name="Category 2" url="/sport/category-2/" isrouter="false"
display="true" controller="sport" action="category" />
<item name="Category 3" url="/sport/category-3/" isrouter="false"
display="true" controller="sport" action="category" />
<item name="Category Routing" url="/sport/:category/" isrouter="true"
display="false" controller="sport" action="category" />
</subitems>
</item>
</subitems>
</item>
</nav>
The XML file is used for the creation of our menu (i’ll describe that in another post) and the routing information. Each item has an attribute “iscontroller” that identifies the routes to create for the application. I created a class Menu_Routing in my library to read the XML file and create the routes.
Menu_Routing.php
<?php
class Menu_Routing {
protected static $_instance = null;
public static function getInstance() {
if (is_null(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
public static function getRoutes() {
$xml = simplexml_load_file(C_APPMAP .'data/nav.xml');
$routes = self::readRoutes($xml);
return $routes;
}
private static function readRoutes($xml) {
$routes = array();
foreach ($xml->item as $item) {
if (trim($item['isrouter'])=='true') {
if (!isset($item['module'])) $item['module'] = 'default';
$routes[] = array(
'url' => trim($item['url']),
'name' => trim($item['name']),
'controller' => trim($item['controller']),
'action' => trim($item['action']),
'module' => trim($item['module']),
);
}
if (isset($item->subitems)) {
$subRoutes = self::readRoutes($item->subitems);
$routes = array_merge($routes,$subRoutes);
}
}
return $routes;
}
}
The function readRoutes returns the routes that has to be created in our Initializer.php (in the function initRoutes()), it just returns an array.
Initializer.php
public function initRoutes() {
$routing = Menu_Routing::getInstance();
$routes = $routing->getRoutes();
foreach ($routes as $routeItem) {
$route = new Zend_Controller_Router_Route($routeItem['url'],array(
'module' => $routeItem['module'],
'controller' => $routeItem['controller'],
'action' => $routeItem['action'],
));
Zend_Controller_Front::getInstance()->getRouter()->addRoute($routeItem['url'],$route);
}
}
Download source
You can download the source of this example here.




May 12, 2010 at 5:33 pm
I think you didn’t understand the inner working of the Zend Framework with the OOP principles. You talk about an initializer.php and a special class Menu_Routing, which isn’t quite the ZF way to add routes to your router.
Most simple is you load the routes from a config. Directly from the application.ini or a seperate (ini/xml) file is much easier. Load the file with Zend_Config (and Zend_Controller_Router_Rewrite is config aware) so you can inject the routes directly:
$config = new Zend_Config_Ini(‘path/to/routes.ini’);
$router = new Zend_Controller_Router_Rewrite();
$router->addConfig($config, ‘routes’);
This can be done with a frontcontroller plugin at routeStartup hook. It’s the preferred method to inject more routes directly to the router.
May 12, 2010 at 7:19 pm
You are right about the way to load the routers of your application with an INI or XML config file. It’s a good method (maybe the best) to load the routes into your router.
What’s the problem with loading in at the Initializer of your application?
May 12, 2010 at 7:24 pm
Loading them from an application.ini or other type of config file with the Zend_Config_… is a great way to do this. I agree on that. I used the XML file for other things like a the menu of the website (on the front-end) etc.. that’s why i choose a XML reading configuration like the one in the post.
May 12, 2010 at 8:16 pm
What’s exactly the initializer you’re talking about? I only know about an index php file which instantiates a Zend_Application, bootstraps it and finally run the app. Inside the bootstrap I use my resource plugins and running the application triggers several frontcontroller plugins & finally dispatches the module/controller/action.
I expect the initializer you’re talking about being a sort-of bootstrap. When you do so, I’m more in favor of Zend_Application with its MVC concepts. Using the framework’s power makes your application more reusable and understandable for other developers.
I’m loading my pages from the database, where every page is able to convert into a Zend_Navigation_Page instance and a Zend_Controller_Route_Uri instance. From XML you might be able to achieve the same results, that’s right.
May 12, 2010 at 8:36 pm
I know the Zend_Application option, i’m doing kind of the same thing only without the Zend_Application class(see the download). The method i’m using with the Initializer is also the "older" method (before 1.8 when Zend_Application was introduced). So as we both mentioned it makes no difference.
Just another question?
Why are you loading pages from a database? The file system loading with .ini files or .xml files is probably faster because you don’t need a database connection with database login etc (I didn’t test it bu i suggest the file system is faster). Are you also loading al your pages from the database?
May 14, 2010 at 9:48 am
To solve this problem, I’m using an ini- or xml-file together with Zend_Application and some resources: Zend_Navigation and Zend_Router
In addition with Zend_Acl and Zend_I18N you have a powerful Navigation- & Routing-System with translated uri-parts and access-control out of the box with Zend_Config!
@see:
Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl();
Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole();
@janwillem
Loading pages from a database might be ok, if you are using a cms which stores all the page information in a database. Use memcache or file cache backend for better performance.