jump to navigation

Boosting the Performance of a PHP-project with an Autoload Class Map April 15, 2013

Posted by Tournas Dimitrios in PHP.

The de facto standard for developing PHP applications is the OOP – model , it’s the most adopted programming paradigm in today’s software design . For organizational reasons , each Class (or Interface)  is defined in its own file . Those files are then stored into a tree-like hierarchical structure . An OOP project is build by instantiating Objects  from those aforementioned Classes ( imagine Classes as blueprints with predefined functionality) . Before a Class can be used (as a blueprint) into our project ,  it has to be imported first (PHP has four “tools” for importing Classes , require , require_once , include  and include_once) . PHP 5 introduced the magic function __autoload() which is automatically called when the code references a class or interface that hasn’t been loaded yet . As time goes on , developers started to release their code-base to the programming community .Unfortunately , each developer adopted his/her own naming convention for defining Class-names . Its a common practice to combine different code-bases onto one single project . Due to the aforementioned “different naming convention” , an __autoload function had to implement different “ways” of importing Classes (usually it was done with “switch or loop statements” ) . The major drawback to the _autoload() function is that you can only define one autoloader within each PHP-project .Later on  (since  PHP > 5.1.2)  , the registration of multiple autoloaders was possible with  SPL’s spl_autoload_register function . A practical example is demonstrated below  :

<?php // A single autoload function
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;

// Multiple autoloaders with SPL's register
function autoloadMail($className) {
    $filename = "mail/" . $className . ".php";
    if (is_readable($filename)) {
        require $filename;

function autoloadLogger($className) {
    $filename = "Log/" . $className . ".php";
    if (is_readable($filename)) {
        require $filename;


PHP 5.3  introduced namespace support  , and a group of people from the PHP community decided to create  the PSR-0 standard which outlines various practices and constraints that must be followed for autoloader interoperability . Later on , the same group created the PSR-1 , PSR-2 and PSR-3 guidelines as an attempt to standardize coding-style and logger-interface practices .

No matter which autoload-method is used to reference a Class , PHP has to search  through all predefined paths (remember the autoload registers) until the required Class is found . This “scan-procedure” is repeated on each and every Class request , which obviously adds an extra overhead on the project’s  performance . Instead of doing runtime heavy directory scans or relaying on a properly configured include path  , the best way to implement an autoloader turned out to be a static Classmap . In simple words , a predefined list of Class-paths instruct the PHP interpreter to “go straight to the meat” instead of scanning the whole directory structure . Of course , the Classmap could be hard-coded (by hand) , that’s not a problem on small projects . On medium to large scale projects though , where tens if not hundreds of Classes are used to structure an application , that would be a nightmare .  A flexible tool to generate such a map alongside a matching function to implement the autoloader is provided by the phpab project  (PHP autoload builder) . This article will guide you through all required steps ( from installation to generating a Classmap ) , just follow along …..

 Installing phpab :

Although my demonstration is made on a Windows-7 machine , the same procedure is applicable on all Operating systems . phpab can be installed using the PEAR Installer . This installer is the backbone of PEAR , which provides a distribution system for PHP packages , and is shipped with every release of PHP since version 4.3.0 . Installing PEAR’s package manager is out of the scope of this article , follow the instructions given on this post , if you haven’t done already . phpab is a command line utility to automate the process of generating an autoload require file with the option of creating static require lists as well as phar archives .  The steps to follow are :

  • Open a terminal window (cmd) and verify that “pear” in installed on your machine (pear without any argument will return a whole list of command-line options)
  • pear config-set auto_discover 1
  • pear install pear.netpirates.net/Autoload
  • verify that phpab is installed by :  phpab  -v  (it will return the version )
  • Note : Installation must be done with administrator privileges . Unix user should use the “sudo” command . On Windows ,  start->All-programs->accessories->right-click on “Command Prompt” and select “Run as administrator” .

The following screenshot demonstrates the installation process on my machine . Notice , I had two errors during my first attempt : 1) phpab depends on “DirectoryScanner” package (which must be installed first) , 2) The “fileinfo” extension wasn’t enabled , keep in mind though , PHP’s Cli  has a totally different “php.ini” file . Enable the extension , by removing the proper “;”  inside the ini-file .

installing phpab on wamp

A simple demonstration of phpab :

To demonstrate phpab’s functionality lets first introspect a simple project . I’ll be using another handy command – line utility (also installed via PEAR) . As seen on the screenshot below , the project’s source code is organized into 14-directories , 35-files (28 Classes and 7 Interfaces) . It seems a simple project , each time a Class is requested the whole directory structure must me scanned until the Class is found .

introspecting a sample project

Lets now improve the performance of our project by generating a Classmap , just open a terminal into the projects source files and run a :
phpab  -o a_custom_folder/autoload.php  src
The “-o” defines the location where the generated Classmap file should be stored . The third option “src” is the folder of the source files (an absolute or relative path ) . Finally ,  the generated “autoload.php” file should be included into our project (directly or via a bootstrap file ) .

<?php // @codingStandardsIgnoreFile // @codeCoverageIgnoreStart // this is an autogenerated file - do not edit spl_autoload_register(     function($class) {         static $classes = null;         if ($classes === null) {             $classes = array( 'bankaccount\\application' =--> '/application/Application.php',
'bankaccount\\controller\\bankaccount' => '/application/controller/BankAccount.php',
'bankaccount\\controller\\bankaccountlist' => '/application/controller/BankAccountList.php',
'bankaccount\\controller\\redirecttobankaccountlist' => '/application/controller/RedirectToBankaccountList.php',
'bankaccount\\factory' => '/application/Factory.php',
'bankaccount\\framework\\controller\\controllerinterface' => '/framework/controller/Interface.php',
 'bankaccount\\model\\bankaccountexception' => '/application/model/BankAccountException.php',
'bankaccount\\testing\\factory' => '/application/testing/Factory.php',
'bankaccount\\view\\bankaccount' => '/application/view/BankAccount.php',
'bankaccount\\view\\bankaccountlist' => '/application/view/BankAccountList.php'
        $cn = strtolower($class);
        if (isset($classes[$cn])) {
            require __DIR__ . $classes[$cn];
// @codeCoverageIgnoreEnd

The output of phpab generated a Classmap , which shows that this project needs to instantiate 32 Classes . Now each time an instance of a Class is needed , PHP will find the Class-path into the Classmap  and wont scan the whole file system (the include path defined into php.ini file ) .

screenshot of a Classmap file
Final thoughts :

The “technique” of a Classmap file isn’t new , nether the only method used to improve the performance of a project by accelerating its autoloading functionality .  For instance , something like APC or memcached  can be used in a production environment . Factors like speed and memory usage  should be taken into account while we plan our strategy . Keep in mind that each time our project’s structure is changed (by adding or removing Classes) , the Classmap file has to be regenerated . Finally , Composer , a  Php dependency manager (which I highly suggest) has this functionality by default . Each time a new package is installed into Composer’s “vendor” folder , the autoload file is updated with a new classmap structure . We could also manually install libraries into Composer’s “vendor” folder , and run a “composer dumpautoload”  command , which will update the classmap file .

Update : Just for completeness , Laravel (a php-framework) , dramatically increase  application’s performance , by optionally use of an  compiled class file which contains all of the classes commonly used  by a request . The Artisan “optimize” CLI parameter (php artisan optimize) is used to create this file . The produced file contains over 80 commonly used Classes .



1. Carlin - April 26, 2013

excellent information. i have learned quite a few very helpful information from your blog. thank you very much.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s