Zend Framework 2 autoloading

12,777

Solution 1

The classmap is there to show PHP the most direct way to a class. It's essentially saying "You you're looking for A\Class\Youre\Looking\For, look no further than this file: xyz.php. This would be expressed like this:

return array(
    'A\Class\Youre\Looking\For' => ___DIR__.'/xyz.php'
)

Without it PHP has to run through the whole autoloader chain, which can be pretty expensive. Why is it saying something about "as we're in development"? Because classmap files are typically generated on the production server by some script. Basically, just don't worry about it too much right now. It's micro-optimization...

The getAutoloaderConfig() method is just there to give you some flexibility in really advanced applications. Most of the time you can just use the SkeletonApplication's and SkeletonModule's boilerplate code and leave it alone. Really, you can even kill the 'Zend\Loader\ClassMapAutoloader' => array(__DIR__ . '/autoload_classmap.php',) part for now.

It's just a hook for future improvements and nothing to worry about too much if you're just starting out with ZF2 (like me ;).

Solution 2

ZF2 has a number of autoloaders available.

The 2 most common (or the 2 which developers interact with directly at any rate) are Zend\Loader\ClassMapAutoloader and Zend\Loader\StandardAutoloader.

  1. The classmap autoloader is usually used at the module level to provide a simple but fast array lookup mechanism. It is configured with an associative array of key => value pairs, with the key representing the class, and the value representing the filename which defines the class.

  2. The standard autoloader, on the other hand, is designed to hold a list of "namespaces" and base directories. What is does is to then build the path to the class referenced, but not yet loaded, by prepending the base directory path for that namespace to the class name, to arrive at the final absolute path to the class file, which it then tries to include. You can quickly populate the classmap_autoload.php file by running either /path/to/ZF2/bin/classmap_generator.php or zftool.phar generate classmap.

Zend\Loader\AutoloaderFactory is designed to manage the various autoloaders, and to make sure there are no conflicts. Ultimately, of course, all autoloading capabilities leverage PHP SPL autoloading.

The purpose of getAutoloaderConfig() is to identify to the autoloader factory which autoloaders are available for this module's namespace.

In the example shown above, that would be, in order of preference, the classmap autoloader, followed by the standard autoloader. If you don't wish to use the classmap autoloader for that module, simple remove the reference from the array returned by getAutoloaderConfig().

The method name getAutoloaderConfig() is reserved. If this method is defined, during the module initialization process, a listener (Zend\ModuleManager\AutoloaderListener) is attached which retrieves the configuration returned by this method, and adds it to the consolidated configuration.

Solution 3

A web application consists of many PHP classes, and each class typically resides in a separate file. This introduces the need of including the files.

As your application grows in size, it may be difficult to include each needed file. Zend Framework 2 itself consists of hundreds of files, and it can be very difficult to load the entire library and all its dependencies this way. Moreover, when executing the resulting code, PHP interpreter will take CPU time to process each included file, even if you don't create an instance of its class.

To fix this problem, in PHP 5.1, the class autoloading feature has been introduced. The PHP function spl_autoload_register() allows you to register an autoloader function. For complex web sites, you even can create several autoloader functions, which are chained in a stack.

During script execution, if PHP interpreter encounters a class name which has not been defined yet, it calls all the registered autoloader functions in turn, until either the autoloader function includes the class or "not found" error is raised. This allows for "lazy" loading, when PHP interpreter processes the class definition only at the moment of class invocation, when it is really needed.

Because each library's vendor uses its own code naming and file organization conventions, you will have to register a different custom autoloader function per each dependent library, which is rather annoying (and actually this is an unneeded work). To resolve this problem, the PSR-0 standard was introduced.

The PSR-0 standard (PSR stands for PHP Standards Recommendation) defines the recommended code structure that an application or library must follow to guarantee autoloader interoperability.

Each module of the web application registers an autoloader, which makes it possible to autoload any PHP class in your modules. This is made with the getAutoloaderConfig() method of the Module class.

ZF2 has a special component named Zend\Loader, which contains implementations of the two commonly-used autoloader classes: the standard autoloader (Zend\Loader\StandardAutoloader) and class map autoloader (Zend\Loader\ClassMapAutoloader).

The fact that ZF2-based application modules conform to PSR-0 standard makes it possible to use the standard autoloader.

The class map autoloader can be used as a faster replacement for the standard autoloader. This autoloader expects you to pass it a class map array. Each key=>value pair of the class map is, respectively, the class name and path to the PHP file containing the class.

The concept of autoloading in Zend Framework 2 is well explained in Using Zend Framework 2 book.

Share:
12,777
ba0708
Author by

ba0708

Updated on June 13, 2022

Comments

  • ba0708
    ba0708 almost 2 years

    I am just starting to look at Zend Framework 2 (and am new to ZF in general), and in the user guide, they are using autoloading when adding a new module. However, I find the explanation to be quite challenging for a rookie. They are adding a Module.php file within the module directory, which among others contains the following code:

    public function getAutoloaderConfig()
        {
            return array(
                'Zend\Loader\ClassMapAutoloader' => array(
                    __DIR__ . '/autoload_classmap.php',
                ),
                'Zend\Loader\StandardAutoloader' => array(
                    'namespaces' => array(
                        __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                    ),
                ),
            );
        }
    

    Now I did some digging around to try and figure out what this autoloading is all about. As far as I understand, the autoloading uses spl_autoload_register() and is a way to avoid having require_once() everywhere in the code. So, when trying to use a class that is not defined, the autoload() method that was registered will be run, which simply does an array lookup and includes the file like below if it was added.

    // Zend/Loader/ClassMapAutoloader.php
    public function autoload($class)
    {
        if (isset($this->map[$class])) {
            require_once $this->map[$class];
        }
    }
    

    This seems clever due to performance. I hope what I just wrote is correct. Based on this, I am trying to figure out what is going on in getAutoloaderConfig() from the first code snippet, but I am quite confused. It seems as if the array that is returned by this method is used for AutoloaderFactory::factory(), but I am not sure for what purpose. Instantiating autoloaders with options it seems, but exactly what that does, I am not sure. I guess the second entry of the array specifies where to find the source files for the module's namespace - at least that would be my guess. The first entry I am, however, not sure about. In the user guide, it says the following:

    As we are in development, we don’t need to load files via the classmap, so we provide an empty array for the classmap autoloader.

    The file just returns an empty array. I am not sure what the purpose of this ClassMapAutoloader.

    Sorry if my point is unclear; basically I am trying to figure out what is happening in getAutoloaderConfig() and what mymodule/autoload_classmap.php is used for. If someone could shed some light on this, that would be much appreciated!