Forget the includes, let PHP autoload it
If you’re a PHP developer who breaks up their classes into separate files, you’re probably aware of the annoyance of having to setup the proper includes at the beginning of every script. There is also careful management of class dependencies to be considered, whereby one class will have to include those classes it uses itself to guarantee they exist when needed.
Starting in PHP5 we were given a better way. PHP5 introduces a new magic function called __autoload(). If this function is defined in the PHP script, it is called whenever an attempt is made to use a class that has not been defined yet. After __autoload() is called PHP will attempt to use the class again, giving the developer one last chance to get the class setup in between.
__autoload() has one parameter, the name of the class or interface (in a string) that the script attempted to use. A simple implementation that includes a class classname saved as classname.php from the include path would be
__autoload($classname)
{
if (is_readable($classname.'php'))
{
include $classname.'php';
if (!class_exists($classname, false) && !interface_exists($classname, false))
trigger_error('Could not load '.$classname, E_USER_ERROR);
}
}
Note I used include instead of include_once. This is because __autoload() will only be called if the class has not already been defined, i.e. the include file has not been included. Feel free to use include_once however, to be sure.
Also note the false parameter I passed to class_exists(). This parameter disables an autoload check for that class – it wouldn’t make sense to autoload the class again if the first autoload failed. With the default true parameter, class_exists will attempt to autoload the class if it doesn’t exist.
__autoload() is a great way to manage a library of classes because you can write your own implementation that knows how to load up your classes when they are needed. Instead of including everything at the top of your scripts, just include the autoloader and it’ll take care of the rest. __autoload() also provides an incentive to write all of your library code as classes (and interfaces) because functions cannot be autoloaded.
Now for some bad news. __autoload() is a bad idea! Why? Because if you were to use it and then add a 3rd party application to your project that also used it you’d get a nasty PHP error stating that __autoload cannot be declared twice. What a bummer! Fortunately in PHP5.1.x the developers solved this problem by giving us the spl_autoload* functions. These behave the same as __autoload() but constitute a stack were your implementation can exist simultaneously with the one belonging to the 3rd party application you just added.
Simply write your own function, call it anything you like, and register it using
spl_autoload_register('my_autoload_function');
Even better, we can also set the autoloader to a method in a class using an array form. Static methods can be used like so
spl_autoload_register(array('My_Static_Class', 'myStaticMethod'));
Dynamic methods can also be used
spl_autoload_register(array(&$class, 'myDynamicMethod'));
Two important things to keep in mind when using spl_autoload* are
- spl_autoload* functions cannot be used in combination with __autoload() – it’s one or the other
- Your implementation of an spl_autoload* autoloader should not error if the class cannot be found, since its possible a second autoloader can find it.