Skip navigation.
Home
That which cannot be rendered in binary is by definition a delusion
 

Reply to comment

: Assigning the return value of new by reference is deprecated in /home/bingoman/public_html/wll_drupal/sites/all/modules/paging/pagination/pagination.module on line 508.

Routing in Zend Framework

One of the tasks (chores, duties) I hate is managing routing within Apache; it involves negotiating with one or more system admins, coordinating across servers, testing, and more than a few unpleasant surprises. Fortunately Zend Framework has an internal routing system that allows you to pre-emptively reinterpret a URL to any Module/Controller/Action (or url) you please.

Routes is a pretty thin component -- in the best possible way; its easy to read and use relatively quickly. I wish I'd known it when I was working at Live Nation and my boss asked me to add SEO links to artists and concerts; I could have, for instance, added the following routes:

/artist/:artist_name/* --> controller = artist, action = index, module = default

This allows for a very agile and customizable URI pattern.

The Mechanics

While you can of course create and insinuate route objects into the front controller I suggest you use a more streamlined approach: put routes in your config.ini (as in this example, from Zupal)

; ----------- ROUTES ---------------

routes.module_scripts.route = "scripts/:script_module/:script_path"
routes.module_scripts.defaults.controller = "resources"
routes.module_scripts.defaults.action = "script"
routes.module_scripts.defaults.module = "administer"

routes.module_images.route = "images/:image_module/:image_path"
routes.module_images.defaults.controller = "resources"
routes.module_images.defaults.action = "image"
routes.module_images.defaults.module = "administer"

routes.model_css.route = "style/:style_module/:style_path"
routes.model_css.defaults.controller = "resources"
routes.model_css.defaults.action     = "css"
routes.model_css.defaults.module     = "administer"

routes.admin_mvc.route = "admin/:module/c/:controller/:action/*"
routes.admin.mvc.defaults._layout = "admin"

routes.admin_mv.route = "admin/:module/:action/*"
routes.admin_mv.defaults.controller = "admin"
routes.admin_mv.defaults._layout = "admin"

Combined with a route loader in Bootstrap.php:

    protected function _initRoutes()
    {

        $frontController = Zend_Controller_Front::getInstance();
        $router = $frontController->getRouter();
        $options = new Zend_Config_Ini(APPLICATION_PATH . DS . 'configs' . DS . 'application.ini', APPLICATION_ENV);
        $router->addConfig($options, 'routes');
    }

These two components will let you drive the routing directly from Zend Framework, mostly, from your config file.

Some Caveats

You'll note the "/*" suffix after some of the routes; this allows you to define the start of a url but retain the ability to pass parameters in the rest of the path.

Also the layout can be set in the route; so that, for instance, if the route was for a special popup context (or in this case an admin page) you can build that right in to the route.

Route variables can be parts of the MVC route (controller, etc) or general params that are returned from the action's _getParam('name') method.

Despite which variables you use in the route, the route will have issues telling two paths with different tokens apart if the surrounding context is identical; thus, the "/c/" is necessary in the second to last route, becuase without it, admin/:module/:controller/:action/* and action/:module/:action/* look identical. i.e., admin/(*)/(*)/(*)/* == admin/(*)/(*)/* from the router's perspective.

You can route directly to other URLs directly; use uri in place of the MCA parameters in the destination.

Why Not Use Apache?

There is nothing "wrong" with apache redirects. I can't say which is more resource conservative, but I'd bet it is Apache. However if you use routes, you don't have to concern yourself with synchronizing external configurations, which makes testing and deployment much easier.

Routes that are external to Zend Framework might double the hit per click, suggesting that a sharing of responsibilities between Zend Framework and Apache would be the most scalable solution for a larger organization.

However, from the political point of view, this is one more bulwark against people who find the MCA pattern too restrictive. the ease with which you can customize URI handling is a great asset for those still trying to push ZF into adoption.

And Of Course, the Fucked Up Part

For some reason if you use routes, Zend_Navigation will interpret urls that it renders from pages objects according to the route that landed you on the page you're on. This means that menus, breadcrumb, etc. will be parsed with strange URL patterns and presumptiions about controller/module/action values as designated in your router. For instance, if I click on a link with admin/ as a prefix, all my menu items will suddenly have admin/ as a prefix! 

To un-fuck up your pages, after you've been routed, (i.e., in an action plugin or a view helper) include this snippet:

        $router = Zend_Controller_Front::getInstance()->getRouter();
        $fake_route = new Zend_Controller_Request_Http();
        $fake_route->setRequestUri('/');
        $router->route($fake_route);

This will flip the front controller back to the default router.

Reply

  • Allowed HTML tags: <a> <p> <span><small> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <embed> <object> <param> <strike> <caption>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options