The latest, and last, release of the Zend Framework 1.x series is just around the corner as ZF 1.12.0RC1 was announced this week. As I still have projects running ZF1 I thought about giving the most interesting new feature (for me) a spin - the new autoloaders which are backported from ZF2.

Note: the code below was updated to work with ZF 1.12.0RC2. Should still work with RC1, too.

I decided using the classmap autoloader as the main autoloader, and the good ol’ standard autoloader as the fallback autoloader. For the classmap autoloader to work we need to create a classmap. ZF1.12 comes with a tool, located in the bin directory, called classmap_generator.php, which will generate the classmap for us:

$ cd /path/to/project/library
$ php /path/to/zf1.12/bin/classmap_generator.php 

This will generate a PHP file called autoload_classmap.php in the library directory and it will have classname - filename mappings of the classes/files from that directory.

Next, need to change the index.php a bit to tell ZF to use the new autoloaders:

<?php
// normal setting up of APPLICATION_PATH and other constants here ...
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
require_once '../library/Zend/Loader/AutoloaderFactory.php';
// As of ZF1.12.0RC2 the Zend prefix is not autoregistered
// with the standard autoloader, so we need to require explicitly
// the ClassMapAutoloader.php
require_once '../library/Zend/Loader/ClassMapAutoloader.php';
Zend_Loader_AutoloaderFactory::factory(
    array(
        'Zend_Loader_ClassMapAutoloader' => array(
            __DIR__ . '/../library/autoload_classmap.php',
            __DIR__ . '/../application/autoload_classmap.php'
        ),
        'Zend_Loader_StandardAutoloader' => array(
            'prefixes' => array(
                'Zend' => __DIR__ . '/../library/Zend'
            ),
            'fallback_autoloader' => true
        )
    )
);
// set up Zend_Application as normal here ...

and that’s about it - the autoloader will load classes from the classmaps, but if it fails to do so, it will fall back to the standard autoloader.

Stripping out require_once calls

The Zend Framework manual has a section on how to improve performance of the framework itself, and one of the suggestion is to strip out the require_once calls from the library. I had to alter that find/sed command combination a bit in order to make it work with the classmaps:

$ find . -name '*.php' \
  -not -wholename '*/Application.php' \
  -not -wholename '*/Loader*' \
  -print0 | xargs -0 \
  sed --regexp-extended \
  --in-place 's/(require_once)/\/\/ \1/g'

If I’m not wrong in reading my “debugging” echo statements, the standard autoloader gets called only once - to load the classmap autoloader itself - everything else is loaded via the classmaps. Pretty cool.

Happy hackin’!