Advanced CodeIgniter Techniques and Tricks

Advanced CodeIgniter Techniques and Tricks

Tutorial Details
  • Difficulty: Advanced
  • Topics: PHP, CodeIgniter
  • Time required: 30 minutes

CodeIgniter is a widely used PHP framework that aims to help developers write better structured code and remove boilerplate tasks from the workflow.

In this article, I’m going to explain some incredibly useful techniques to use when developing applications using CodeIgniter.


1. Easier Configuration Parameters

When creating libraries (or anything that requires configuration values) for our applications, we often need to use configuration parameters in order for it to be able to perform its tasks. When doing so, we can use the snippet shown below to obtain the configuration values.

$value	= $this->config->item( 'some_item' );

This is fine, if we have just a couple of configuration parameters, but when we need to extract a dozen configuration parameters or so, loading values this way can be very annoying. Wouldn’t it be great to load every parameter like the array we use in the configuration file? In order to do just that you need to load it in the following way.

$this->load->config( 'config_file', true );
$options	= $this->config->item( 'config_file' );
// $options['some_item'];

And with that single line, our entire configuration file will be placed in the $options array. And to further sweeten the deal, using this technique also makes sure you avoid the name collision problem in configuration files. This way, your parameters can be named anything you’d like without worrying about other configuration files.


2. Allowing Optional Configuration Options

Building up on our earlier point, imagine a scenario where we’d like to pass parameters to our library from either a configuration file or an options array when loading it. Maybe we’re using the same library in different parts of our application and the config options cannot be the same for each use case.

To be able to do this, place a private _options member in you library and use a constructor like the following.

private $_options	= array();

public function __construct( $options = array() ) {
	if ( is_empty( $options ) ) {
		$this->load->config( 'config_file', true );
		$options	= $this->config->item( 'config_file' );
	}
	
	$this->_options	= $options;
}

After this, you can access your parameters through the private _options array within your library, and, just like the previous example, you’ve avoided name collision problems with the keys in your configuration files.


3. Leveraging HTML Emails

The need to send HTML emails through your app is omnipresent, be it a newsletter or some automatic welcome message. Usually, you’d do this by hand coding the corresponding HTML in the message parameter of our email object (been there, done that).

Well, it’s no secret that the above method is pretty ugly. The following tip is not quite a trick but merely a way to take advantage of some CodeIgniter functionality where it makes sense.

Personally, I prefer this approach as I manage a few sites where I need to send newsletters, and several other HTML emails, and using templates will significantly ease up the process.

In your application’s views folder, create a folder called emails and place any HTML email you’d like to send inside it, with the corresponding structure to be rendered by email clients. And now, in the method where you shoot off the emails, you can use the following code:

public function send_mail() {
	$this->load->library( 'email' );
	$this->email->from( 'jdoe@gmail.com', 'John Doe' );
	$this->email->to( 'jane_doe@gmail.com' );
	$this->email->subject( 'Some subject' );
	$this->email->message( $this->load->view( 'emails/message', $data, true ) );
	$this->email->send();
}

A couple of important things to keep in mind when using this technique:

  • The email library must be set up to be able to send HTML emails
  • The data object used when loading the view should contain the options used in the view
  • With this approach, we’re using the built-in functionality of retrieving the content of a view file instead of sending it to the output class by setting the third parameter to true when loading the view.

4. Managing Application Versions

Let’s face it: almost every recent PHP application is a backend service or an API. If you have used the Google Maps API, you’ve probably noticed that Google allows us to pass a version parameter for us to tell it which version we’re going to make use of.

Wouldn’t it be nice if we can do this in our CodeIgniter applications? This way, we can create new versions of our software while supporting legacy versions to ensure backwards compatibility.

With this technique, we’ll be able to use a single CodeIgniter installation to handle multiple versions of our application using the same index file. We’ll be able to choose the version by passing a v parameter in the request.

There are a couple of things in order for this to work. First off, I’m going to rename my application folder. Since this is the first version of my API, I’ll simply name it 1.0.0. After this, I’m going to rename my index.php file, call it 1.0.0.php and change the application_folder line in it. Replace line 75 with:

$application_folder	= '1.0.0';

Cool, now our application version is 1.0.0. Are we going to call that 1.0.0.php file instead of index? Absolutely not! Let’s create a new index.php file and add the following code to it.

define( 'API_VER', 'v' );

array_key_exists( API_VER, $_REQUEST ) ? $v	= $_REQUEST[ API_VER ] : $v = '1.0.0';

if ( file_exists( "{$v}.php" ) ) {
	if ( is_dir( dirname( __FILE__ ) . "/{$v}" ) ) {
		require dirname( __FILE__ ) . "/{$v}.php";
	} else {
		$error	= new stdClass();
		$error->error		= true;
		$error->description	= 'INVALID_API_VERSION';
		echo json_encode( $error );
		exit;
	}
} else {
	$error	= new stdClass();
	$error->error		= true;
	$error->description	= 'INVALID_API_VERSION';
	echo json_encode( $error );
	exit;
}

Here, we’re defining the parameter that we’ll use to choose the version. If no version is passed, we use the 1.0.0 version. If a version is passed, we make sure there’s a corresponding file and folder for that version. Otherwise, we throw an error.

To add more versions, we’d simply have to copy our 1.0.0 folder and the 1.0.0.php file, rename them according to the version we’re going to create, change the application_folder variable in the file and start working on the next version of our API. When we feel comfortable enough with it, we can make it the version by modifying the index.php file.


5. Serving Separate Response Formats

Dot notation? No, I’m not talking about Objective-C messages. If you have used the Twitter API or something similar, you’ll remember that at the end of the method call, you can specify the format you want the response in. As I really like to create RESTful services using CodeIgniter, I like to add this functionality to them even though I’ve always use JSON.

In order to do this, we need to take advantage of CodeIgniter hooks to preprocess our URI. We’ll use two hooks for this process, and we’ll set a config item to set the response format accordingly.

First off, what are hooks? According to the CodeIgniter user guide,

CodeIgniter Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files

In plain English, they’re a way to change the normal execution flow of an application. Although we don’t want to do precisely that here, we do want to preprocess our URI before the CodeIgniter Router class has a chance to inspect it. With that in mind, we’re going to make use of the “pre_system” hook.

In order for us to use hooks we have to enable them. To do that, open the config.php file under the config and set the enable_hooks item to true.

$config['enable_hooks']	= TRUE;

We now need to add the hook that will take care of the pre-routing process. Inside the config folder in your application folder, open the hooks.php file and add the following code:

$hook['pre_system']	= array(
	'class'		=> 'Router',
	'function'	=> 'route',
	'filename'	=> 'router.php',
	'filepath'	=> 'hooks'
);

What this code does is that it tells our application to run the route method of our Router class inside our hooks folder. A quick note here: the filepath parameter is the path to the file that has the method you want to call, and it MUST be relative to your application folder WITHOUT a trailing slash.

Now we need to create the class and method that this hook is going to call. In your hooks folder (if it’s not there, create it) inside your application folder, create a new file, name it router.php and place the following code in it.

if ( !defined( 'BASEPATH' ) ) exit( 'No direct script access allowed' );

class Router {
	
	private static $_format	= '';
	
	public function route() {
		$request				= strstr( $_SERVER['REQUEST_URI'], '?', true );
		if ( !$request ) {
			$request			= $_SERVER['REQUEST_URI'];
		}
		$parts					= explode( '.', $request );
		self::$_format			= $parts[ sizeof($parts) - 1 ];
		
		if ( self::$_format == 'json' || self::$_format == 'xml' || self::$_format == 'rss' || self::$_format == 'atom' ) {
			$_SERVER['REQUEST_URI']	= substr( $request, 0, ( strlen( $request ) - strlen( self::$_format ) - 1 ) );
		} else {
			self::$_format	= '';
		}
	}
}

CodeIgniter Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files

A couple of things to note here. First off, you’ll notice that I’m using an static class member to store the type of the request. That’s because we’re getting the response format correctly, but we cannot tell the rest of the application about it. At this early point of the application execution, the config class is not yet loaded so we need to use another hook. With that in mind, we’ll need to make it static so it’s not overridden when we call the next hook.

Right at the beginning, I’m checking for an ? symbol, so the rerouting here won’t conflict with any parameters passed through the URL. The strstr method will return the string BEFORE that character as the third parameter is set to true. Do keep in mind that this behavior was added in PHP 5.3.0, so if you’re using a previous version, you’ll need another way to obtain the part of the string before the ? symbol.

Because of the way we’re retrieving the requested response format from the URI and then setting the REQUEST_URI key manually for the CodeIgniter Router, we need to check that the output requested is valid. If not, we let the application handle the request without interfering.

Now we have identified the requested response format but our controllers doesn’t know about it. I think that a clean way to inform this is with a config parameter. In order to set it we need to use another hook. The first two hooks are pre_system and pre_controller.

However, at this point we cannot use the get_instance method, meaning we can’t set a config item, so we’ll use the post_controller_constructor hook. As long as you don’t intend to use the response format config item in the controllers constructors this technique will work.

After the pre_system hook in the hooks.php file add the following code.

$hook['post_controller_constructor'] = array(
	'class'		=> 'Router',
	'function'	=> 'config',
	'filename'	=> 'router.php',
	'filepath'	=> 'hooks'						
);

As you can tell, this hook is calling another method in the same class that we use to retrieve the requested response format. In the Router class after (or before) the route method, add the following code.

public function config() {
	$CI		=& get_instance();
	$CI->config->set_item( 'response_format', self::$_format );
}

In this method, we’re setting a configuration option called response_format with the format retrieved on the route method.

Finally, to use this response format in your controllers (or anywhere in your application) use the following code.

$format	= $this->config->item( 'response_format' );

And with that, you can retrieve the requested format and parse the result accordingly. As to parsing the response, I leave it as an exercise to the reader.


Conclusion

I hope you’ve found some of these tips useful. As you may have noticed, I’ve focused on RESTful services since, in my opinion, they are what we as PHP developers should be focusing on.

I look forward to your comments and thank you so much for reading.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.maomuffy.com Mfawa Alfred Onen

    Nice Article Carlos. I use Codeigniter for some projects and some of your tricks looks interesting. Thanks.

  • Francis

    Awesome tutorial! We’re doing a lot of CI projects in the workplace and this helps keep me fresh full of ideas. Any favorite tutorials on creating a REST API in CI? A lot of my development is Ajax heavy and it would be nice to be able to utilize CI to its full potential in regards to an AJAX client / REST server.

    • http://philsturgeon.co.uk Phil Sturgeon

      For working with REST APIs in CodeIgniter take a look at this article:

      http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/

      • Matt Soltani

        Just have to point out that Sturgeon’s REST API library for CI is awesome. Good code and very useful!

      • Jordan

        I can second that his REST library is awesome.

      • robert

        +1 from me too. I used Codeigniter for several projects, but the best part was writing a project for my diploma where I use Codeigniter and Sturgeon’s RESTful library, combined with a single-page JS application :)

    • http://bitslice.net Carlos Cessa
      Author

      Thanks a lot, I’m glad you find it useful, currently I’m working on another tut to create a full REST service along with a client application using Backbone.js, it should be up soon

      Cheers

  • Dan

    Nice, CI tuts rule. Thanks!

  • kasakka

    Wouldn’t the #2, the options thing be better if it loaded the config file anyway but you could use the $options to override some of it? So instead of just using the config file or the options array you would array_merge the two so you always have a set of default options.

    • Jordan

      Yes. This is a much better way of doing it.

  • http://www.mikhailkozlov.com Mikhail

    Any reason to use hooks as oppose to extending core classes? Pros/cons?

    • http://bitslice.net Carlos Cessa
      Author

      I think it depends on what you’re trying to achieve, hooks are generally to perform small alterations to the normal CodeIgniter Application flow, they’re just a way to get a little peak and tap something before letting the system run normally, this can be, like in this case, take a parameter from the request.

      Extending core classes normally have a bigger impact that using a hook, and also by using a hook you just alter the behavior of the Application flow a little, you don’t provide a new method to say, your CodeIgniter base object, or something like that

      Cheers

  • http://www.fleet-management-solutions.net/ Callie Walls

    nice post in codeigniter my website is a codeigniter MVC.

  • http://www.snilesh.com Nilesh

    thanks for these advanced codeigniter techniques……

  • http://danharper.me Dan Harper

    For #2, a more robust solution would be to merge any configuration options passed to the constructor with the default options from the config files. eg:

    private $_options = array();

    public function __construct( $options = array() ) {
    $this->load->config(‘config_file’, true);
    $defaults = $this->config->item(‘config_file’);

    $this->_options = array_merge($defaults, $options);
    }

    • http://bitslice.net Carlos Cessa
      Author

      You’re right I haven’t though in overriding some parameters, I guess that would make perfect sense :)

      Cheers

  • http://philsturgeon.co.uk Phil Sturgeon

    As somebody who has been using CodeIgniter for several years, and who is now a contributing developer – I would never do any of these things.

    #2 is wrong, CodeIgniter will be default load any config file which has the same name as the Library, or will allow an array of config values to be passed in to override those. No hacking required.

    As for building a REST API I have already written a NetTuts tutorial on how this is done:

    http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/

    The United Nations use this code, so it can’t be that bad.

    • http://bitslice.net Carlos Cessa
      Author

      Ok so CodeIgniter does load by default a config file with the same name as the Library, and what you say about CI allow automatically an array of config values, I don’t know how you would access those in your Library without handling them accordingly in the constructor.

      As far as your REST API, I have no doubt that is great, although I don’t see the point of showcasing here, in any way I attempt to say “this is a REST API” I’m just pointing some tips that REST services may benefit from, the point of this whole tuts was to show how to use some CI features, I don’t consider myself to be some expert (as you seem to think of yourself) but this techniques are things I use on some real projects some big, some not so much, but I can’t think how you can say that using versions is a bad thing, and the last one, I just happen to like the Twitter API and how the serve their content, that’s the aim of the last tip

      Cheers

      • http://philsturgeon.co.uk Phil Sturgeon

        I am a freelance consultant who travels the world working with teams on their CodeIgniter projects to help insure quality, I think it is fair to say that I am an expert on this subject.

        You have taken a defensive stance, but I am not being offensive. I am just saying that these are either over-complicated or not “advanced”. If I was talking about advanced CodeIgniter techniques I’d cover base controllers, autoloading, composer integration, multiple database connections, some CI 3.0 features, unit testing, selenium, etc. And 2? Come on dude, that is just how the email library works.

        I look forward to your post about CI and backbone, I’ll be curious to see the differences between this and the FuelPHP post by Dan Harper:

        http://marketplace.tutsplus.com/item/realtime-web-apps-with-backbone-fuelphp-pusher/2442378

      • Alexis

        Carlos, please.
        It’s *just* Phil Sturgeon. If you’re writing this article and not knowing who he’s, you should definitely not be writing any article on CodeIgniter.

      • Carlos Cessa
        Author

        lol

      • http://yoosuf.me Yoosuf

        :D

  • http://blog.husainad.com/ hw

    I might be wrong, but it seems to me that #5 is an overkill. Can’t we just implement something like that by writing a new routing rule and passing the format as a parameter?

    • http://bitslice.net Carlos Cessa
      Author

      It might be very well possible, I haven’t give it much thought to that approach, however from the top of my head I think that to do that you’ll need to overwrite the Router class, and take care of the multiple routing alternatives that CodeIgniter supports.

      I was trying to along with the tip show a little about CodeIgniter hooks, and give an example of how and why to use ‘em, and also that tip is aimed to create a Twitter-like RESTful service with CodeIgniter

      you could pass the format as a parameter but that was exactly what I was trying to avoid, ’cause I think that it looks a little ugly, but that’s just me

      cheers

  • Kapil Verma

    People using codeigniter .. if you can/are using 5.3 .. give laravel a shot

  • David Stanley

    The only point I would agree with is the email statement, although that is almost obvious. As for the rest, not so much.

    • http://bitslice.net Carlos Cessa
      Author

      The purpose of all of the tips above were to make a little easier some tasks, as for points 4 and 5 those are things to do to create RESTful services, in a Twitter-like way, and also I was showing a little about CodeIgniter hooks,

  • Sk1ppeR

    I’d like an article that covers something about Laravel PHP framework. It’s a great one taking advantage of PHP 5.3+ with namespaces and whatnot.

  • http://ferus.info Maciej

    Hey – i have intermediate expirience with CodeIginiter, but I was always wondering if I can create controller and pass a variable/id to the index() function i.e

    http://yourapplication.com/viewPhotos/37
    Any simple thoughts?

    • http://bitslice.net Carlos Cessa
      Author

      You definitely can, but you need to pass the method you are calling as well, index in this case, like so:

      http://yourapplication.com/index.php/viewPhotos/index/37

      or

      http://yourapplication.com/viewPhotos/index/37

      if you set mod_rewrite to avoid using “index.php”
      hope this helps

      cheers,

      • http://ferus.info Maciej

        is there any short way to get rid of this ‘index’ part of url? viewPhotos//37

    • http://northlander.org Dan Bowling

      If you’re trying to manipulate the URL structure, use the routing class. It can get rid of the index for you.

      That being said, I would tackle that problem differently. Instead of a viewPhotos controller, I’d have a photos controller, with a view method. The URL will look just as clean, and it will be a bit easier to maintain. This way, your URL would be http://yourapplication.com/photos/view/37

      • http://www.atomicon.nl Atomicon

        Hey Maciej,

        the following snippet gets rid of your “index” in the URL

        (just paste the following code into your controller)

        public function _remap($method, $params = array())
        {
        if (is_numeric($method)) //is the 2nd param a number?
        {
        $params = array($method); //push the the method on the stack (ID)
        $method = ‘index’; //method changing to index;
        }
        if (method_exists($this, $method))
        {
        return call_user_func_array(array($this, $method), $params);
        }
        show_404();
        }

        FYI for more information about the _remap function read:
        http://codeigniter.com/user_guide/general/controllers.html

        Cheers

  • http://studiodesigned.org Igor M

    Well the #1 isnt the best solution..

    i find the built in function much more easier.

    config_item(‘item_key’);

  • thecodingdude

    No offence to the codeigniter team, but it’s a pretty poor framework. Just like at Kohana (which was based on Codeigniter).

    Kohana = Codeigniter done right.

    • http://edmundask.lt Edmundas

      Can you elaborate on such statement? Give me a few good reasons where CodeIgniter could be considered a poor framework (keep in mind that we’re talking about framework’s core, not the fancy features).

      I had been using CodeIgniter for years and it is a great framework. However, it all depends on what you’re looking for. Over the years I have come to realize that CodeIgniter, unlike other frameworks, does not enforce strict rules on how to use it. Yes, it has MVC and such but it doesn’t ask you to use a specific built-in authentication system, asset management library etc. Just ask the developers who originally created CodeIgniter, they’ll agree with what I’m saying here.

      Not so long ago I started shifting to Ruby/Ruby on Rails and found it odd how strong-opinionated RoR really is. There was a huge debate over coffeescript when it was introduced to Rails as a default. That right there indicates how frameworks have very different ideas and vision behind them.

      The only reason I’m mentioning this is because I assume you referred to CodeIgniter as being a poor framework because it does not have feature-rich libs by default, only the essentials (routing, input, validation, etc) and is not using some newer PHP stuff such as namespaces.

      As far as Kohana goes, I can’t remember what was the exact reason for basically “forking” CodeIgniter but I’d guess it was because some people had different opinions on what a framework should look like. That’s fine by me, whatever helps developers code their ideas smoother and faster.

      Overall, CodeIgniter is great at what it does. The reason I chose CodeIgniter over CakePHP, Symfony and other PHP frameworks that were at the time, was because of easy setup, configuration and most importantly – documentation. Doing things MY WAY was a breeze and I didn’t need to build workarounds for things that I wanted to do. At the time that’s what sold me to use CodeIginter.

  • http://www.webmasterdubai.com webmasterdubai

    HI guys any tutorial about CI cache, a much need tutorial for CI

  • Hoang Phuc

    Thanks for this tutorial !

  • Timothy Aaron

    Re: Application Versions – If you want to use a non-default version, what is the best way to pass that value?

    • Carlos Cessa
      Author

      Sorry for the late reply, if you’re using the code on this tutorial, you’d pass the version as a “v” parameter, in either your GET or POST request

  • http://webduos.com Webduos

    this blog is definitely an example of a huge help for me since i am just starting a blog myself. It help me to understand codeigniter

  • http://www.tutosytips.com johanso

    with CodeIgniter can create interesting things, but I prefer to use jQuery

    • http://www.facebook.com/arjunrajm Arjun Raj

      still i can’t understand how did you compare CodeIgniter and jQuery ?
      one is a sever side php framework and another is client side java script library. Both are performing in different extreme ends.

    • wew

      bego

    • Cary Hartline

      Are you insane?

    • Jorge Torres

      Funny thing is, both can be used together

    • Daniel Van Rensburg

      Must be from the Special School

  • http://byronbakerdesign.com Byron

    Shouldn’t this:

    $this->load->config( ‘config_file’, true );

    be this according to documentation:

    $this->config->load(‘config_file’, true);

    ????

  • Sam

    Very informative article. Thanks!

  • http://bertcompton.wordpress.com/ Jerry England

    CodeIgniter is a powerful PHP framework with a very small footprint, built for PHP coders who need a simple and elegant toolkit to create full-featured web applications.

  • http://vernonaustin.weebly.com/ Wing Winters

    I cannot keep in concepts what was the real objective for usually “forking” CodeIgniter but I’d think it was because some people had different opinions on what a framework should look like. That is awesome by My employee, whatever allows developers value their principles better and faste.

  • http://www.etatvasoft.com/php-frameworks/codeigniter-development.php Katell Brooks

    Using CodeIgniter since a long time but never new of any such tricks or techniques
    before. As such CodeIgniter used to eases my work but now with the help
    of these it will eases my work upto more extent.

  • http://abbotfrost.webnode.com/ Abel Mcknight

    I wish Designer have discovered some of these guidelines useful. I’ve targeted on RESTful solutions since, this blog view, they are what we as PHP designers should be concentrating on this web page.
    .

  • Ekta Jain

    Thanks for sharing these useful tips. As a CodeIgniter developer, they are quite useful for me…

  • Mongaru

    Hi Carlos, nice tricks for CI, I would like to know if there is a way to create HTML components for CI. Like for example the discuss comment that it is used in this post, if I would like to encapsulate the comment feature how would I do it in CI, I know helpers but how do I insert the js code for my component on a helper. Do you have any ideas on this.

  • http://fitzpatrick.yolasite.com/ Leslie Stephens

    I knew that CI have new functionality has been applied without affecting the customization at all.Offers flexibility and easy management With MVC based framework.

  • ssss

    CI IS SHIT!! very bad framework, the worst perhaps for idiots,

    • Trent Ramseyer

      Care to elaborate?

  • Kevin Remisoski

    It’s funny how so many trolling tools just say codeigniter is shit and disappear with no explanation even when asked. In my experience, people like this are just too stupid to figure out an easy light weight framework most likely because they know little about PHP and are hoping for a noob proof solution.

  • http://twitter.com/matthewfedak matthewfedak

    Where does the $data array come from in the email example. Surely it should be passed in a s parameter to the send email function?

  • sachin

    how to send email in background and the view is called first in codeigniter

  • http://www.facebook.com/people/Matthew-Browne/4810559 Matthew Browne

    Nice tips about determining response format, but wouldn’t it be easier to use a URL like user/view/id/2?response_format=json and then just check the value of $this->input->get('response_format')?