Quantcast
Channel: Karl Katzke's Blog » routing
Viewing all articles
Browse latest Browse all 2

Zend Framework: If controller not found, use default

$
0
0

I ran into a big problem with a client site this past week, and I owe it all to my coworker Jeff Carouth for helping me see it from a different angle.

My client’s specification called for two behaviors that monkey with ZF’s usual domain.tld/module/controller/action or domain.tld/controller/action routing mechanism. They wanted to use a subdomain to load the client’s customer-customized skin (i.e. customer1.domain.tld, customer2.domain.tld) — no problem. The issue arose when they also wanted to have domain.tld/customer1 and domain.tld/customer2 work the same as the subdomain. Obviously, customer1 and customer2 are not going to resolve to valid controllers, which results in an exception being thrown and the error page being displayed unless a valid static route is found…

Jeff made a huge contribution by looking at the problem at a much lower level. I was considering using the routing mechanism to accomplish this by adding a whole bunch of static routes ahead of the default router. But with an install that’s supposed to support hundreds of my clients’ customers, it’s not exactly practical to load that list for every single request! Instead, the customer name being passed in as a controller is indeed an exception, and should be handled as such!

To make this work, the first thing that needs to change is that Zend_Controller_Front needs to throw exceptions instead of passing them to the error controller. You can do this by using

$front = Zend_Controller_Front::getInstance();
$front->throwExceptions(true);

The following feels to me like a code stink, but for all intents and purposes is a valid coding practice when handling exceptions. We’re basically going to tell the front controller to “run the front controller once with the default routing rules, and if it breaks, run again with a custom routing rule.”

try {
  $front->run(BASE.'app/controllers');
} catch  (Zend_Controller_Dispatcher_Exception $e) {
  $myRoute = new Zend_Controller_Router_Route(
      '/:customer/:action/*',
      array(
         'controller' => 'index'
         ,'action' => 'index'));
}
  $router->addRoute('default',$myRoute);
  $front->setRouter($router);
  $front->throwExceptions(false);
  $front->run(BASE.'app/controllers');
}

I don’t think you actually need that $front->setRouter() call in there, but it’s not hurting anything … Do note the call to restore the default behavior of Zend_Front_Controller::throwExceptions() back to false. That’s important or your error module won’t have exceptions routed to it correctly.

Thanks, Jeff! Owe you a beer for that one.


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images