Easy Reverse Routing with CodeIgniter

Easy Reverse Routing with CodeIgniter

By Kenny Katzgrau | Published: September 21, 2010

I really can’t stand hard-coding URLs in the views or controllers of my application — and I’m sure most other people can’t either. Here’s an extension for the CodeIgniter Router class that I wrote that gives you a nice way to write routes that are reversible and also have the ability to take parameters.


class MY_Router extends CI_Router
    private $_reverseRoutes = NULL;

    CONST ARR_ROUTE_POS      = 0;

    function _parse_routes()
		// Do we even have any custom routing to deal with?
		// There is a default scaffolding trigger, so we'll look just for 1
		if (count($this->routes) == 1)

		// Turn the segment array into a URI string
		$uri = implode('/', $this->uri->segments);

		// Is there a literal match?  If so we're done
		if (isset($this->routes[$uri]))
			$this->_set_request(explode('/', $this->routes[$uri][self::ARR_ROUTE_POS]));

		// Loop through the route array looking for wild-cards
		foreach ($this->routes as $key => $val)
			// Convert wild-cards to RegEx
            //echo "$key --> ";
			$key = preg_replace('/\:\w+/', '[\w\-_]+', $key);
            //echo "$key <br />";
			// Does the RegEx match?
			if (preg_match('#^'.$key.'$#', $uri))
				// Do we have a back-reference?
				if (strpos($val[self::ARR_ROUTE_POS], '$') !== FALSE AND strpos($key, '(') !== FALSE)
					$val = preg_replace('#^'.$key.'$#', $val[self::ARR_ROUTE_POS], $uri);   

				$this->_set_request(explode('/', $val));

		// If we got this far it means we didn't encounter a
		// matching route so we'll set the site default route

    function _buildReverseRoutes()
        $reverse_routes = array();

        foreach($this->routes as $route => $info)
            # If this is a default route or scaffolding key, ignore it
            if(!is_array($info)) continue;

            $name = $info[self::ARR_ROUTE_NAME_POS];
            $reverse_routes[$name] = $route;

        $this->_reverseRoutes = & $reverse_routes;

    function reverseRoute($route_name, $args_keyval = array())
        if($this->_reverseRoutes === NULL)

        if(!array_key_exists($route_name, $this->_reverseRoutes))
            show_error("No reverse route found for '$route_name'");

        $route = $this->_reverseRoutes[$route_name];

        foreach($args_keyval as $key => $val)
            $route = str_replace("(:$key)", $val, $route);

        return $route;

Drop that into application/libraries, then rewrite your routes to look like this:

$route['users/(:username)']  = array('users/$1', 'user-homepage');
$route['companies/(:slug)']  = array('companies/$1', 'company-homepage');

Let me explain that.

CodeIgniter lets you use wildcards in your routes like (:any) or (:num). That’s no more with this extension. Basically, anything you put in (:[name]) format with be treated like (:any). That’s handy, and I’ll tell you why.

Once you rewrite you routes, you can now call a new method on the routing class when you need to, say, redirect the user to his homepage after login:

  # login was successful, and we now have a $user object
  redirect($this->router->reverseRoute('user-homepage', array('username' => $user->username));

The reverseRoute method takes two parameters: The route you want to send the use on, and any wildcards that you need to fill in the url. For the user-homepage route, there is a (:username) wildcard in the route. We can pass the appropriate fill-in for that wilcard with the second parameter with an associative key-value array.

A redirect to a company-homepage would look like:

  # ...
  redirect($this->router->reverseRoute('company-homepage', array('slug' => $company->slug));

Then in the future, if you feel like changing your routes, go no further than the routes file! Mucking around in views is a recipe for broken links.





1 thought on “Easy Reverse Routing with CodeIgniter”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s