Tuesday, February 7, 2012

Maintain a DRY philosophy in Codeigniter


This is my second part in why I really like Codeigniter, it follows on from this post. Whereas the first post was a comparison of Codeigniter and Yii, this post is purely Codeigniter related.

When you first learn Codeigniter, you will build your controllers, models and views and plug them all in accordingly. Ok, now imagine a situation where you have multiple controllers, i.e. News, Content and Testimonial - all are part of the application and all the controllers need the same basic information/variables passed through to the views for output. To make life easier for yourself you could create a very 'fat' controller and keep all functionality inside said controller, but my preference is always to use multiple 'thin' controllers as it makes application much easier to manage.

Imagine you have to build a large application which has many, many different subject areas, with multiple features, i.e. Admin areas, customer areas, public areas and you need to do it in an efficient manner. This is where the DRY (Do not repeat yourself) approach comes in handy, very handy.

For example an array of dynamically generated links that are being created from a class you have written. Using a DRY philosophy you only want to call your link generating method once, not once in every controller or method/action. This is how to do it.

In a lot of Codeigniter examples found on the web you will see the following being used:

$this->load->view('view-page',$data);

...which passes the data from your controller in to your view.

However, you do have another tool that you can use accomplishing this task and that is the method:

$this->load->vars();

So in your your constructor method, you are going to use the $this->load->vars() method to pass through your links array in to each of your methods/actions like so:

class news extends CI_Controller {

function __construct() {
    $data['links'] = $this->link_generator->get_links();
    $this->load->vars($data);
}

function list_news() {
    //code to go here
}

function news_item() {
     //code to go here
}

}



Using the above, every single method/action that is called will be able to successfully access the links variable.

Now, and this is where it gets a little more complicated, we are going to take the above and combine it with extending the CI_controller, so that we can use the code we created in the construct method in all our controllers, so that we do not repeat ourselves. Please believe me, once you have mastered extending the Basic CI controller, the amount of work you will find yourself doing will decrease considerably.

As I do not like to steal other people's work I will point you in this direction: here which will take you to a post from a chap named Phil Sturgeon. Once you have mastered that, you should be able to apply the examples above in to base classes you create using Phil Sturgeon's methods.

I for example, create a base class for every major area of the website and most of my applications have this structure when it comes to base classes.

-- base_admin
-- base_public

...with each controller extending the ones above. Using this method then allows me, for example to add in all my session and user identity checks within my base admin class' constructor and it only has to be called once, rather than in every single controller.  Of course, this is only one simple example, believe me, you can do some really cool stuff with this. I have used this method in so many ways; in shopping sites, user based driven sites, so please give it a go, you'll be extremely glad you did.



Labels: , , , , ,