Kohana 3 Routing – Part 1: Static routes and Subdirectories

Part 1 | Part 2

The complexity of Kohana routing is really not as daunting as it first appears–especially if you’ve the leisure to browse the cleanly written, well organized code. However, for those who lack the time (or desire) to parse libraries, Kohana can present some stumbling blocks to a newbie early on the learning curve. Routing is one area many have difficulty fully grasping–just Google ‘Kohana Routing’ and witness the ensuing carnage. The goal of this article series is to help provide introduction to understanding Kohana 3 routing.

I’m going to go slow, but before we begin, there are several assumptions:

  1. You’ve installed and have a working instance of Kohana
  2. You’re installation has the .htaccess rewrite working to suppress ‘index.php’ part of the URL
  3. You’re familiar with the fundamentals of MVC
  4. You’re controllers are found in application/classes/controller/
  5. You’ve made at least one pass thorough the ‘Getting Started’ section of ‘Official’ kohana documentation

How Kohana Routes

The process for routing is pretty straightforward. Kohana 3 maintains an associative array of Route objects. When looking to match a URL to a route the process is as follows:

  1. Kohana iterates through the array of Routes in the order in which the Route objects were inserted into the array
  2. The first Route found that is a match for the URL is the Route which will be used.
    • Once a matching route has been found the Route array will never be evaluated again by the normal Kohana routing process
    • REMEMBER: The FIRST match, not necessarily the BEST match is the one that is selected
    • So… be careful with the order in which you create routes. Keep more specific route first and general/default routes last
  3. Kohana tries to find a the controller and method indicated by the matching Route
    • If it is found, it’s invoked
    • If either the controller or specified method does not exist, a 404 Error is triggered

Now that we had that quick introduction, lets jump into building our routes!

The Basic Static Route

Open the application/bootstap.php file and go to the end of it. By default it’s recommended that you place your routes here, so for this overview, we will. New routes are added to kohana via the Route class’s set() function. If you have existing route entries already in your bootstrap, comment them out for now–it’s very easy to get turned around when messing with routing, it’s best to temporarily minimize sources of futz. We’re going to start with very basic static routes and work our way up to more complexity in later articles

First, lets create a new Controller, we can call it Controller_Foo. Create a file named Foo.php inside the controller folder. Add the following code to this file:

<?php

class Controller_Foo extends Controller {
    public function action_bar(){
        $this->response->body('In controller Foo, action Bar!!!!');
    }
    public function action_kung(){
        $this->response->body('In controller Foo, action Kung!!!!');
    }

}

Now add the following code to the bottom of the bootstrap.php

 $myroute = Route::set('foobarroute', 'foo/bar');
 
 $myroute->defaults(array(
        'controller' => 'Foo',
        'action'     => 'bar',
    ));

In a browser, go to http://yoursite.com/foo/bar. The result should be a webpage with the text:

In controller Foo, action Bar!!!!

Here’s what happened:

  1. We create and set a route using the Route::set($name, $url) function with 2 parameters, the a unique name of the route and the url to match against
    1. The function creates and inserts a new route into an associative array of routes maintained by kohana, with a key of the ‘foobarroute’.
    2. set() returned the newly created route
  2. We set the defaults for the route, an array with 2 entries, the controller and action (a member function of the controller to be called when this route is taken)
  3. When browsing to foo/bar, the URL specified by the route matched, and controller and function in the default array is called.

Pretty simple right? Also very limited. This route named ‘foobarroute’ will only ever trigger on the exact path http://yoursite.com/foo/bar in the URL. One itsy-bitsy exception to the rule… http://yoursite.com/foo/bar will also work–Kohana truncate trailing slashes, much to the ire of SEO conscious folks.

Key thing to remember, make sure the name you pass as the first argument to Route::set() is unique! Otherwise, fun times will definitely not follow, although things may appear to work.

For fun, lets change the route a little. Change the ‘action’ in the default array to be ‘kung’ instead of ‘bar’. While we’re at it, since the set() function returns a route object, we can chain the default() function and get rid of the unnecessary variable declaration. This isn’t just done to keep OCD javascripters happy, but help keep things nice and neat as your routes grow. Your final route should look like this:

   Route::set('foobarroute', 'foo/bar')->defaults(array(
        'controller' => 'Foo',
        'action'     => 'kung',
    ));

Now and access the URL in a browser, when you browse to http://yoursite.com/foo/bar you should see:

In controller Foo, action Kung!!!!

Basic Subdirectory Routing

Ok, so you get the gist of static routes… the URL must be an exact match, and the array used to set defaults defines the exact controller and action fuctions to use.

Before we move on to more advanced routing, how do you handle sub directories? Lets create a folder Boom inside controllers. Inside the Boom folder create a file Bang.php with the following code:

<?php
class Controller_Boom_Bang extends Controller {

    public function action_pow()
    {
        $this->response->body('In controller Boom_Bang, action pow!!!!');
    }
       
}

For routing however, we have two different ways to handle things. Kohana is smart enough to take underscores and convert them to directories when searching for classes (a common Zend flavored pre-PHP 5.3 namespace hack). So we could use the following:

 Route::set('bangpowroute', 'boom/bang/pow')->defaults(array(
        'controller' => 'Boom_Bang',
        'action'     => 'pow',
    ));

However, for the same result we can also set the ‘directory’ key in the default array as follows:\

 Route::set('bangpowroute', 'boom/bang/pow')->defaults(array(
    'directory' => 'Boom',
        'controller' => 'Bang',
        'action'     => 'pow',
    ));

Either works. Also, you can add underscores to the directory parameter similar to the contoller, for sub-sub-directories. Say you had a controller named Controller_Boom_Subboom_Bang in a file application/classes/controller/Boom/Subboom/Bang.php, you’d set the following route:

 Route::set('bangpowroute', 'boom/subboom/bang/pow')->defaults(array(
    'directory' => 'Boom_Subboom',
        'controller' => 'Bang',
        'action'     => 'pow',
    ));

Regardless, pick a route style, and browse to http://yoursite.com/boom/bang/pow and you should see:

In controller Boom_Bang, action pow!!!!

Conclusion

With this you get the basics enough to create any manner of static routes, explicitly. Part 2 of this series will go over adding variable components to of the URL

1 comment to Kohana 3 Routing – Part 1: Static routes and Subdirectories

  • KC

    In regards to your last tip about the sub_directories and using underscores (‘directory’ => ‘Boom_Subboom’,).
    I’m not sure what version of Kohana 3 you are using but in version 3.2 you can use the forward slash instead of an underscore. So ‘directory’ => ‘Boom/Subboom’,. But thanks for the tutorial. It helped me figure that out.

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>