This entry was posted on Monday, July 14th, 2008 at 10:34 pm and is filed under PHP5. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
It Seemed Like a Good Idea at the Time
I’ve recently noticed a few articles advocating the use of PHP’s __autoload function to manage project includes. I’m sure these authors have good intentions, but the __autoload functionality became outdated before anyone really even started using it.
The __autoload function was introduced way back in PHP5 as a means to dynamically load class files as you need them. It was definitely a step in the right direction, and using it was a good design choice for all but the smallest object-oriented projects.
In case you missed it, __autoload replaced the need to call individual includes for each external class file. For instance, your only option for loading a file “KrunkTastic.php” which contains the “KrunkTastic” class definition used to look like this:
-
include(‘classes/KrunkTastic.php’);
-
-
$obj = new KrunkTastic();
Clearly, this could get to be a big pain as your project grew. You were then faced with loading every class you’d ever need, or remembering to load them yourself every time you needed to get your krunk on. Both of these solutions sucked. Luckily, the PHP developers agreed, and gave birth to a good first draft solution.
Once a function called __autoload is defined, PHP will call it when it comes across a class definition it doesn’t know about. This gives you a chance to load the class file before PHP tries to access it. Consider the previous example:
-
//This function can be defined anywhere
-
function __autoload($className)
-
{
-
include("classes/$className.php");
-
}
-
$obj = new KrunkTastic();
When the PHP5 parser gets to the line that instantiates a new object of type “KrunkTastic”, it realizes that no class by that name has been declared. It does, however, notice that we’ve defined a function called “__autoload”. PHP then calls our __autoload function, passing the name of the unknown class as our “$className” parameter. This gives us one last change to include the proper class file. That’s right, PHP4, you suck.
Abomination!
This all seems pretty slick, but within this architecture lurks a deep and insidious evil. Since __autoload is declared as a global function with a fixed name, it can only be declared once. This severely limits the developers of third-party toolkits and libraries in their use of this functionality. If you integrate libraries into your application that have already declared an __autoload function, you can’t re-declare it for your own code.
This means that, while it’s a perfectly adequate solution for smaller projects, __autoload is pretty crappy for the big projects that need it the most. The PHP team, who would not stand for such a bummer, then crafted a much more workable solution.
Enter spl_autoload
PHP 5.1.2 introduced the spl_autoload family of functions. This gave developers the ability to switch from a single, global __autoload function to a global autoload stack of functions, registered using spl_autoload_register. An example:
-
//Register an autoload function
-
function myAutoLoader($className)
-
{
-
include("classes/$className.php");
-
}
-
spl_autoload_register(‘myAutoLoader’);
-
//Register another autoload function
-
function myOtherAutoLoader($className)
-
{
-
include("include/$className.php");
-
}
-
spl_autoload_register(‘myOtherAutoLoader’);
-
//Register a static method from a class as an autoloader
-
class AutoLoader
-
{
-
{
-
include("classes/$className.php");
-
}
-
}
-
$obj = new KrunkTastic();
It should be noted that as soon as you make a call to spl_autoload_register, any legacy __autoload function will be ignored. That’s what it deserves for being old and busted. If you really want to use it, you have to manually add it to the spl_autoloader stack with a call to spl_autoload_register(’__autoload’).
Conclusion
Using legacy autoloading via __autoload has been obsolesced by superior autoloader stacking, which offers much more flexibility, and interoperability with third-party libraries. Go forth and prosper, and stop loading your class files manually like a masochist. Unless you’re a masochist, in which case I respect your lifestyle choice.

July 22nd, 2008 at 12:54 pm
Thanks for the advice! I was using “__autoload” in my projects but from now on i won’t do it anymore.
July 22nd, 2008 at 3:03 pm
Thanks for not posting just a critique/rant but also pointing out the correct solution.
July 22nd, 2008 at 8:22 pm
The SPL autoloader is definitely the way to go. Too bad the PHP site isn’t pushing SPL more, especially in the right places in the documentation (for example, the __autoload() page …)
July 22nd, 2008 at 10:37 pm
I haven’t coded much PHP in the past couple of years. I loved the idea of __autoload when it came out, but the Library problem did suck. Kinda makes classpath seem not so bad.
July 29th, 2008 at 1:33 pm
Well, your article is realy interesting.
But why every article on php optimisation tell to avoid the use of __autoload ? Is it the same with the new spl_autoload ?
http://www.hm2k.com/posts/50-php-optimisation-tips-revisited
I think it is time consuming to use autoload mecanism. If you can handle manually the includes in your project you have to do it !
July 31st, 2008 at 11:45 pm
Tim,
Let me start by saying i love your content and there begins the problem. I like to read articles away from the computer and so print them out (it is just more comfortable, and prevents sunburn from my monitors). However, I can not print a usable copy from your site. When printing much of the site is center-aligned making the code examples much harder to read, and labels the line numbers which overlap the code.
Would you consider implementing a printer stylesheet?
Thanks,
Steve