Let’s say you have the file Rectangle.php which contains the definition for a Rectangle class. Before you can create an instance of the object elsewhere in your code, you first need to pull in the Rectangle.php file, perhaps by writing something like this:
<?php require "Rectangle.php"; $rect = new Rectangle(42, 25);
Normally we put each class’ definition in its own file for better organization, and so you need to require/include each of the class files you want to use. If there are only a few files then it isn’t too much of a problem, but oftentimes that’s not the case. It can be very cumbersome to load a large library including all of its dependencies like this.
In this article I’ll walk you through the “history of autoloading,” from the older to the current PSR-0 standard autoloader approach found in many PHP frameworks such as Lithium, Symfony, Zend, etc. Then I will introduce you to the ClassLoader component from the Symfony2 project for PHP 5.3 which follows the PSR-0 standard.
Warning: Most of the code samples in the beginning of this article demonstrate deprecated approaches. It would be unwise to use them in production. I recommend you use one of the PSR-0 standard autoloaders instead.
Autoloading in the “Olden Days”
PHP 5 introduced the magic function __autoload() which is automatically called when your code references a class or interface that hasn’t been loaded yet. This provides the runtime one last chance to load the definition before PHP fails with an error.
Here’s an example of an extremely basic __autoload() implementation:
<?php
function __autoload($className) {
$filename = $className . ".php";
if (is_readable($filename)) {
require $filename;
}
}
It’s a good idea to make sure a file exists before you try to include it, but sometimes the file may be there but will not have sufficient read permissions so it’s better to use is_readable() over file_exists() which will for test both conditions.
The major drawback to the __autoload() function is that you can only provide one autoloader with it. PHP 5.1.2 introduced spl_autoload() which allows you to register multiple autoloader functions, and in the future the __autoload() function will be deprecated.
The introduction of spl_autoload_register() gave programmers the ability to create an autoload chain, a series of functions that can be called to try and load a class or interface. For example:
<?php
function autoloadModel($className) {
$filename = "models/" . $className . ".php";
if (is_readable($filename)) {
require $filename;
}
}
function autoloadController($className) {
$filename = "controllers/" . $className . ".php";
if (is_readable($filename)) {
require $filename;
}
}
spl_autoload_register("autoloadModel");
spl_autoload_register("autoloadController");
Generally the functions are called in the order they’re registered, but the order can also be affected by additional arguments passed to spl_autoload_register().
It’s important to remember that once a function has been registered with spl_autoload_register(), the __autoload() function will no longer be called. If you have an __autoload() function you want to run as part of your autoloader chain, then you’ll have to register it with spl_autoload_register().
Of course, the implementations of the autoloading functions I’ve shown this far have been rather simple. Real-world autoloaders are more complex.
Before real namespace support was introduced in PHP 5.3, developers devised their own approaches to prevent naming collisions. The PEAR Coding Standard used underscores to prefix class names with their directory path; the class Zend_Translate for example would be defined in the file Zend/Translate.php. The autoloader needed to replace the underscores with directory separators to locate the definition.
Also, different developers adopted different conventions when it came to naming their class files, for example the files might end in .php, .class.php, .inc, etc. Some libraries may be installed in different paths as well. The loader needed to look in various places for them, so now the loader begins to look like this:
<?php
function __autoload($className) {
$extensions = array(".php", ".class.php", ".inc");
$paths = explode(PATH_SEPARATOR, get_include_path());
$className = str_replace("_" , DIRECTORY_SEPARATOR, $className);
foreach ($paths as $path) {
$filename = $path . DIRECTORY_SEPARATOR . $className;
foreach ($extensions as $ext) {
if (is_readable($filename . $ext)) {
require_once $filename . $ext;
break;
}
}
}
}
Autoloading is a useful idea, but was an idea that desperately needed some standardization.
PSR-0 Standard
After PHP 5.3′s introduction of true namespace support, a group of people from the PHP community decided to create the PHP Standards Working Group in 2009 (later renamed to the Framework Interoperatability Group) and establish the PSR-0 standard which outlines various practices and constraints that must be followed for autoloader interoperability. Below are the requirements for PSR-0 compliance:
- A fully-qualified namespace and class must have the following structure
\<Vendor Name>\(<Namespace>)*\<Class Name>. - Each namespace must have a top-level namespace (“Vendor Name”).
- Each namespace can have as many sub-namespaces as it wishes.
- Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system.
- Each underscore in the class name is converted to a
DIRECTORY_SEPARATOR. The underscore has no special meaning in the namespace. - The fully-qualified namespace and class is suffixed with
.phpwhen loading from the file system. - Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lower case and upper case.
According to the PSR-0 standard, there should be a top level directory with the vendor's name and then the package name, so the directory tree will look like this:

The classes would then be namespaced accordingly:
<?php
namespace Vendor\Package;
class Example
{
}
Thus, the class definition for \Doctrine\Common\Connections would be found at /path/to/project/lib/Doctrine/Common/Connections.php, and \Symfony\Core\Request at /path/to/project/lib/Symfony/Core/Request.php. The PSR-0 standard does not mandate what the base /path/to/project/lib portion of the path is, and conforming autoloaders offer different methods for its resolution. Some will allow you to register the directory, some will search PHP's include_path, and some offer you both. Below is an example taken from the accepted PSR-0 standard.
<?php
function autoload($className)
{
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strripos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
require $fileName;
}
This gist by Jonathan Wage is a sample SplClassLoader implementation that can load your classes if you follow the autoloader interoperability standards. It is the current recommended way to load PHP 5.3 classes that follow these standards.
You can use any one of the PSR-0 compliant autoloaders from frameworks such as Symfony, Pear2, AuraPHP (which is for PHP 5.4+), etc. and adhere to the rules above with your own code to take advantage of autoloading without the uncertainties I discussed previously.
Using Symfony's Autoloader
The Symfony2 project is a component-based framework for PHP 5.3 and greater which you can use as a component library or as a full-stack framework. You can download Symfony’s Autoloader, the ClassLoader component, via different means -- pear.symfony.com, packagist, or from GitHub.
Here's the directory structure of Symfony's ClassLoader component:

Using the component then looks like this:
<?php
require_once "/path/to/Symfony/Component/ClassLoader/UniversalClassLoader.php";
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespace("Symfony\Component" => "/path/to/symfony/components");
$loader->registerNamespace("Monolog" => "path/to/monolog/src/");
$loader->registerPrefix("Zend_", "path/to/zend/library");
$loader->register();
The registerNamespace() method is used to inform the autoloader where the given namespace's base directory maps to on the file system and accepts a namespace as its first argument and path as its second value. You can also register multiple namespaces in a single call with the registerNamespaces() method.
<?php
$loader->registerNamespaces(array(
"Symfony\Component" => "/path/to/symfony/components",
"Monolog' => "path/to/monolog/src"));
The registerPrefix() method is used to register pseudo-namespaces which was used by Pear, Zend, and other libraries and frameworks before real namespace support was implemented in PHP as we have already covered above. You can also register mulitple ones with the registerPrefixes() method and passing it as an associative array.
<?php
$loader->registerPrefixes(array(
"Zend_" => "/path/to/zend/library",
"Twig_" => "path/to/twig/library"));
If you are using the Alternative PHP Cache (APC), a free and open source opcode cache for PHP, then you can may want to consider using the ApcUniversalClassLoader class. The ApcUniversalClassLoader extends the UniversalClassLoader but uses apc_store() and apc_fetch() to store lookup information in APC's cache. The standard UniversalClassLoader will of course work with APC, but the additional behavior offered by the ApcUniversalClassLoader class afford extra performance benefit.
<?php
require_once "path/to/Symfony/Component/ClassLoader/UniversalClassLoader.php";
require_once "path/to/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php";
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
$loader = new ApcUniversalClassLoader("apc.prefix.");
The ApcUniversalClassLoader accepts a prefix with its constructor. For more information on APC, I suggest reading the APC documentation.
Summary
In this article we have discussed autoloading, from its early days to the current PSR-0 standard which has become widely adopted across many PHP frameworks. Recently, David Coallier tried to push the SplClassloader class into PHP 5.4 to offer native PSR-0 compliant autoloading functionality, but for various reasons it didn't happen. Maybe in the future we will see it added. (See the C extension at gist.github.com/1310352.)
Now the current hot discussion in the working group is focused on caching. If it's something you'd like to be part of, feel free to join the discussion!
Image via Matyas Szabo / Shutterstock



A very informative article, nice job.
“Now the current hot discussion in the working group is focused on caching. If it’s something you’d like to be part of, feel free to join the discussion!”
Where exactly does this discussion take place? I don’t know how much I could contribute but I’d love to eavesdrop.
http://groups.google.com/group/php-standards
Hi Bryce,
Thank you . I guess Tim may have forgot to place the link, I will notify him , so it will help all. Here is it https://groups.google.com/forum/?fromgroups#!forum/php-standards
https://github.com/php-fig/fig-standards
I didn’t know __autoload was to be deprecated.
Thank you for the comments . Yes __autoload is discouraged and may be deprecated or removed in the future.
Thank you for your very informative article. I think, an other autoloading mechanism is the use of classmaps. For example: “ClassMapAutoloader” in ZF2.
Yes Symfony2 also provides a classmap loader , generator etc. You can have a look into https://github.com/symfony/ClassLoader
It seems to be a syntax error (array items without array()):
$loader->registerNamespace(“Symfony\Component” => “/path/to/symfony/components”);
$loader->registerNamespace(“Monolog” => “path/to/monolog/src/”);
Not sure what you mean , see the registerNamespace() and registerNamespaces() methods. Namespaces accepts array .
https://github.com/symfony/ClassLoader/blob/master/UniversalClassLoader.php#L162
https://github.com/symfony/ClassLoader/blob/master/UniversalClassLoader.php#L177
Of course it supports, but array declaration in highlighted code is invalid.
Oh I hear you man.
Thank you for looking more carefully. I can guess now, you have really gone through this. This is a trick to know how many of them read it carefully ;-).
If you use namespaces between double quotes you should escape the backslash.
“Symfony\Component” -> “Symfony\\Component”
Or else an “\n” will become an newline.
Even better is to always use single-quotes (”), since your not using any special characters inside the string.
Hi Sebastiaan Stok,
Thank you for the comments and I agree with you that we can use single quotes.
In this case double quotes also works for there is no ‘\n’ coming :-) . I will ask to make the correction so there is no doubt regarding it :-) .
Thank you.
I tried the approach with spl_autoload and namespaces and I figured out that it doesn’t work properly. At least not yet (PHP 5.3.9). I tried to use classes and namespaces and to do something like this:
// myClassA.class.php
namespace app/classes;
abstract class myClassA { // implementantion }
// myClassB.class.php
namespace app/classes;
class myClassB extends myClassA{ // implementation }
// myClassC.class.php
namespace app/classes;
class myClassC {
function __construct(myClassA $object){ // code here }
}
//test.php
$myObject = new myClassB();
$classCItem = new myClassC($myObject);
And this works with the “old” autoloading method (without namespaces and spl_autoloader) since $myObject is considered a myClassA object type also. Using the namespaces and spl_autoloader I got an error saying that the type of $myObject is not myClassA,
Any hints on this?
I read a post on a blog saying that the __autoload() was going to get deprecated soon. So I want to get this thing “fixed” :)
Thanks in advance! :) (Sorry about the lonnnngggg post :] )
Now your code
class myClassC {
function __construct(myClassA $object){ // code here }
}
//test.php
$myObject = new myClassB();
$classCItem = new myClassC($myObject);
Look myClassC constructor , you expects myClassA object , if you want to use any class objects don’t mention about it. Hope this helps !
Teaching myself this so that I understand what’s happening I wrote the following which uses php’s include_path to find the correct file…
class Config {
static function AutoloadRegister() {
spl_autoload_register(array(“Config”, “PSR0_AutoLoader”));
return TRUE;
}
// this autoloader requires the folder/file name structure to match the namespace hierarchy.
// the SPL autoloader will automatically search through the various include_path paths to find the right folder
static function PSR0_AutoLoader($classname) {
if (!class_exists($classname)) {
require_once(str_replace(“\\”, DIRECTORY_SEPARATOR, $classname).”.php”);
}
return TRUE;
}
// use the include path function to add base paths for various namespaces.
static function Add_Include_Path($path) {
$include_paths = explode(PATH_SEPARATOR, get_include_path());
if (!in_array($path, $include_paths)) {
$include_paths[] = $path;
set_include_path(implode(PATH_SEPARATOR, $include_paths));
}
return TRUE;
}
}
Config::Add_Include_Path(“/path/to/folder/with/packages”);
Config::AutoloadRegister();
Hey Beanie,
Autoloaders, in many of its forms and flavors should have state and be instantiable as well, just like any other class out there. While trickily tempting at first, don’t get caught in the trap of using class constructs as namespaces. Make the your autoloader’s methods dynamic, not static, thus opening up the door for exploiting the benefits that Polymorphism provides right out the box. Using classes as fancy wrappers for plain vanilla procedural code doesn’t just mean you’re doing real OOP.
Thanks for the comments Alex. Some interesting points you’ve raised. I accept that one shouldn’t be using static methods and one should embrace extensability :). To be fair this was a quick and dirty approach that I created as a proof of concept so that I could understand the autoloader as well as PHP’s include_path. With regard to your point about using objects as wrappers for procedural code, ultimately that is exactly what is happening when you get into the function of an object.
To be honest, I’ve been looking for information on PSR0 autoloading and was quite excited to see the headline of this article. However, I was disappointed to find that it didn’t really explain how to do it other than to say ‘use my framework’.
Agreed. Feel proud about yourself, as you’ve done quite a nice job with your “firstborn” namespaced autoloader :-). Just implement a few additional methods that add some state to it, and of course, make sure to throw away the static methods once and for all. If you’re interested in playing around with PSR-0 class loaders, and getting your own one up and running with minor hassles, you might want to fork this https://gist.github.com/221634.
Hi Beanie ,
I am not sure what made you think that we didn’t cover the PSR-0 autoloader.
I have shown a simple example of the directory structure of a PSR-0 standard.
PSR-0 doesn’t think of autoloading as looking through the include path, though some vendors provide it.
Thank you Alex Gervasio for pointing out @jwage ‘s gist. I didn’t point to it since the link and the sample were available at https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md . Yes it was a mistake that the links were not added, which seem to be lost when moving to wordpress. I will point to Tim regarding this.
Sorry about the links everyone. I don’t know what happened but I’ve got them added back now. Also, Hari asked I add the reference to the gist Gervasio pointed out, which I’ve done. Hopefully this will clear up the confusion some readers have had. And thanks, Hari, for being available to answer the questions!
Hi Tim ,
Thank you for taking time to making the corrections. We are sorry about it. Thank you for the questions to make the article much cleaner we hope. Let us know if anything is missed, we will try to resolve it.
Please post a sample __autoload example ….