RSS for Andrew Cairns

Autoloading Resources in Codeigniter

I have personal ‘beef’ with the CodeIgniter loader – I just dont like it. Personally, I may not want every class I load to be instantiated, nor may I want every loaded class to be added as a member.

The CI Loader also maintains an array of singleton classes, but this logic shouldn’t be determined by a loader.

This is where spl_autoload_register comes in handly. With very little effort, we can remove most of the dependency on CI’s loader and create new instances of

There are several ways to add an autoloader to CodeIgniter. Typically, a library item would be created and added to the autoload.php configuration.
Alternatively, a hook can be created to add support at an earlier stage of execution.

In this example, I’ll walk through the steps required to create the library-based autoloader. First, lets create a new file in the libraries folder called autoload_register.php

<?php

spl_autoload_register( 'Autoload_Register::register' );

class Autoload_Register {

	public static function register( $insClass ) {
		var_dump( $insClass );
	}

}

Next, add ‘autoload_register’ to the libraries array within the autoload.php config file.

$autoload['libraries'] = array( 'autoload_register' );

Once this has been added, refresh your browser. You should see something like:

string ‘CI_Autoload_register’ (length=20)
string ‘MY_Autoload_register’ (length=20)

Checking for these classes is part of CodeIgniter checking if the requested class is an extension of the CI Core.

Before we move on, create a tester.php library item you wish to automatically load. Once this has been created, open up the welcome controller and just before the view is loaded add:

$oTester = new Tester();

When you refresh your browser, you should be presented with a nice Fatal Error saying the class Tester could not be found.

Now, lets update our autoloader to do a little more than output some information.

<?php

spl_autoload_register( 'Autoload_Register::register' );

class Autoload_Register {

	const CI_PREFIX		= "CI_";

    public static function register( $insClass ) {
		$sPrefix = substr( $insClass, 0, 3 );

		if ( $sPrefix == self::CI_PREFIX ) {
			return;
		}

		$sFile = APPPATH . 'libraries' . DIRECTORY_SEPARATOR . strtolower( $insClass ) . EXT;

		if ( file_exists( $sFile ) ) {
			require_once $sFile;
		}
    }

}

Creat, now we can directly instantiate any item within the libraries folder. Lets extend this a little to include our models.

<?php

spl_autoload_register( 'Autoload_Register::register' );

class Autoload_Register {

    const CI_PREFIX     = "CI_";

    public static function register( $insClass ) {
        $sPrefix = substr( $insClass, 0, 3 );

		$sSuffix = strrchr( strtolower( $insClass ), '_' );

		switch( $sSuffix ) {
			case '_model':
				$sDir = 'models';
				break;
			default:
				$sDir = 'libraries';
				break;
		}

        $sFile = APPPATH . $sDir . DIRECTORY_SEPARATOR . strtolower( $insClass ) . EXT;

        if ( file_exists( $sFile ) ) {
            require_once $sFile;
        }
    }

}

Excellent, now we are checking if the class ends with ‘_Model’ and changing the path. So can we directly load our models now without using CodeIgniter’s loader? – Well, not yet. If your model extends CodeIgniter’s CI_Model class, you will get an error saying the class CI_Model can’t be found.

The simplest way to solve this issue is to use require_once when the suffix ‘_model’ is detected.

<?php

spl_autoload_register( 'Autoload_Register::register' );

class Autoload_Register {

    const CI_PREFIX     = "CI_";

    public static function register( $insClass ) {
        $sPrefix = substr( $insClass, 0, 3 );

		$sSuffix = strrchr( strtolower( $insClass ), '_' );

		switch( $sSuffix ) {
			case '_model':
				require_once BASEPATH . 'core/Model' . EXT;
				$sDir = 'models';
				break;
			default:
				$sDir = 'libraries';
				break;
		}

        $sFile = APPPATH . $sDir . DIRECTORY_SEPARATOR . strtolower( $insClass ) . EXT;

        if ( file_exists( $sFile ) ) {
            require_once $sFile;
        }
    }

}

And there we go!

Granted, this is a simple implementation of an autoloader however it will serve as a good starting point for anyone that also feels the constraints of CodeIgniter’s loader.

  1. Did something very similar myself. I have beef with alot of the way CI works. It’s a create framework, just missed the point on a few areas. My base CI install is nearly not recognisable now. I’ve implemented autoloading for controllers, meaning finally I can autoload various base classes – yay simpler controller inheritance. Will maybe write it up similar to how you have done here :)

    My next, unaddressed ‘beef’ is sessions handling! That needs sorted!

    Good article btw!

    • Thanks Dave, appreciated!
      CI isn’t my framework of choice anymore because of the whole ‘super object’ and the way it handles everything as singletons.
      Until it gets rebuilt to be more PHP5.3 friendly, I’ll be building everything I can with FuelPHP :)

Leave a Response

*