PHP Autoloading

Monday, 22nd February 2010

Autoloading is the process of automatically loading classes when needed wthout having to go through the traditional include() and require() directives. This helps PHP developers work without having to worry about whether the class that they need has already been loaded or not.

To achieve this, PHP 5 provides the __autoload() magic method that is called automatically whenever a class / object is being referenced while not being defined. If a definition exists for that class, the magic method will not be invoked. If a definition does not exist, the __autoload() method will be invoked before giving up and generating a warning / error message.

So how does auto loading work in examples?

The steps are pretty simple:

  1. Define a function __autoload($class) that will be automatically passed the name of the class that is being loaded.
  2. Provide an implementation for that function that tries to search / find / load the class as needed by the application.

Take the following example to be able to better explain this point.

Given fhe following directory structure within an application:

app |
.......| public
............| index.php
............| images
...................| ...
............| style
...................| ...
.......| library
............| Db
...................| Mysql.php
...................| Oracle.php
............| Output
...................| Xhtml.php
...................| Xml.php
...................| Ajax.php

if we try to load the mysql.php file  into index.php, our PHP code would normally look as follows:

include(ROOTDIR . "/app/library/Db/Mysql.php");

Assuming that ROOTDIR is a defined constant pointing to the root directory of our application, this statement will ask the PHP interpreter to load the file mysql.php from the given path.

The same will need to be done everytime we need to use any file from within the library folder. This, however, can be automagically done through the __autoload() magic function that was described above. The code below is what can be used and I will explain, after it, its many advantages.


function __autoload($className) {
    $filePath = str_replace("_", "/", $className);
    $fileName = LIBRARYDIR . '/' . $filePath . ".php";
    require_once $fileName;
}


The code above is taking the class name ($className) and replacing all occurrences with '_' with a '/' to build up the complete path to the file. If our class is named Db_Mysql, the__autoload() function will automatically build the path to the file and load it.

Inside the index.php file, we will simply use our class without having to include it first but we will need to pay attention to how we name our classes

An example of how the index.php file will look like will follow and is explained in details:

 


function __autoload($className) {
    $filePath = str_replace("_", "/", $className);
    $fileName = LIBRARYDIR . '/' . $filePath . ".php";
    require_once $fileName;

}

$x = new Db_Mysql();


When we try to create a new instance of Db_Mysql, the PHP interpreter will notice that it is not loaded and will automatically invoke the __autoload() function passing it Db_Mysql as the class name.

 

$filePath will hold the value Db/Mysql

$fileName will have the value  <path to application>/app/library/Db/Mysql.php

and the file will be automatically required.

It is worth noting that as of PHP 5.3, you can try to place the autoload() magic method within a try { } catch block. Any exception thrown while trying to load the file can be catched and, thus, different locations can be provided for autoloading.

Also, another nice feature is available with the Zend Autoloader which provides namespaces for loading objects. In other words, you can define many locations to be used for autoloading and the Zend Autoloader will search these locations every time a new object is being loaded.