Hostname matching with Zend_Controller_Router_Route_Hostname

April 2nd, 2010 | by: Chris Woodford

The Zend Framework offers and handy little tool for hostname matching. This means that you can introduce variables into your application’s URIs. For example, you may want to let users go to a URI like http://chris.yoursite.com or http://neil.yoursite.com and then use the “chris” or “neil” part to determine what content is displayed.

The first thing you have to do in order to use hostname matching, is to setup your server such that *.yoursite.com resolves to wherever your ZF application is running. In most cases this is probably just your domain. For example’s sake, let’s say we setup our server so that *.yoursite.com resolves to the ZF app running at yoursite.com

Once that’s in place, you can start using Zend_Controller_Router_Route_Hostname. Defining a hostname route is pretty straightforward:

 
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
    ':username.yoursite.com',
    array(
        'controller' => 'profile',
        'action'     => 'index'
    )
);

So what is happening here is that you’re telling the router that any time it see’s something like chris.yoursite.com, to take the “chris” part and store it in a variable called username, then route to the index action of the Profile controller. If you’re familiar with ZF and defining routes, this will seem pretty trivial.

Here’s where things get tricky. Our $hostnameRoute is matching the hostname, so this route will match any path since the hostname will be part of any path for your site. This is where route chaining comes into play. If you’re not familiar with route chaining, I suggest you read the Zend_Controller_Router_Route_Chain section of the ZF manual. You can find it here. The point of chaining the routes is so that you can first match the hostname and then match any number of subsequent routes.

Let’s put this all together with a concrete example, craigslist.org. When you go to craigslist.org it gives you the option to go to URIs like toronto.craigslist.org or ottawa.craigslist.org. From there you get URI’s like toronto.craigslist.org/msg and ottawa.craigslist.org/msg. What this means is that we want the hostname matching to be applied to _every_ URI first, then we’ll match the path to a route.

 
// let's load all the routes for the site (i like to use an ini file)
$routerConfig = new Zend_Config_Ini(
    APPLICATION_PATH . '/configs/routes.ini',
    APPLICATION_ENVIRONMENT
);
 
// create a new instance of the router
$router = new Zend_Controller_Router_Rewrite();
 
// add all of our routes into the router
$router->addConfig($routerConfig, 'routes');
 
// create our hostname route for our site
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
						':city.craigslist.org',
						array(
						      'module' => 'default',
					              'controller' => 'index',
					              'action' => 'index',
					          )
      					);
 
// loop through all the routes in the router and create
// a chain with the hostname route
foreach ($router->getRoutes() as $key => $route) {
 
	// this will overwrite the existing route with our route chain
	$router->addRoute($key, $hostnameRoute->chain($route));
 
}
 
// lastly, set the router on the front controller
$frontController->setRouter($router);

And that’s all there is to it. The trickiest part is getting the hang of the route chaining – once you’ve got that down, you’re good to go.

Digg it!

One Response to “Hostname matching with Zend_Controller_Router_Route_Hostname”

ronen said:

June 24th, 2010 at 6:46 am

hi

can you publish the bootstrap and the routes.ini

or email me this so hi can see how it is all put together

thanks

Post a Comment:

*
To prove that you're not a bot, enter this code
Anti-Spam Image