Zend Framework 2 Module Manager
In this article, we will look at Zend Framework 2’s module system and why it is such a central part of Zend Framework 2. Afterwards, we will go into more details in terms of the Module Manager and briefly discuss how it works along with autoloading.
The Module System
One of the key features of Zend Framework 2, in comparison with its predecessor, is the module system. Its purpose is to enable developers to write self-contained modules which are easy to plug into existing applications and hence greatly increase code reuse. While Zend Framework 1 did allow the separation of code into modules, it was usually not without significant effort to integrate a third party module into an application.
In Zend Framework 2, each module provides its own configuration files which are then merged together with the entire application’s configuration files by the module manager. As a result, the configuration required for a module to function is provided within the module itself, and therefore there is no need to spend time configuring an application’s configuration files in order for the module to integrate with the application.
For instance, most applications will need to provide some basic functionality; registering, logging in, logging out, recovering passwords, etc. This related functionality would be suitable for a “User” module which could then be reused across development projects.
Another example could be that a website needs a blog. Rather than developing one’s own blog, one can make use of existing modules that are available. This saves both time and money. The alternative could be to use a parallel blogging system such as WordPress. However, it is easy to imagine the kind of challenges this would bring; if the blog has to integrate with the existing caching or logging system, for instance, this would be complicated. Also, the blog’s data would most likely be stored in a separate database, and if the latest blog posts were to be displayed on the application’s front page, this could prove to be a challenge. This functionality would have to make use the blog’s API, feed or database. Another challenge could be if the layouts were to be aligned; the design would have to be maintained in parallel. If a module could be used, all of these integration challenges could be avoided.
The Module Manager
The module manager is responsible for loading the project’s modules by iterating through those defined in config/application.config.php. When doing this, it triggers a sequence of events for each module. Therefore, very little actually happens within the ModuleManager class itself; the loadModules() method simple triggers events so that the processing happens in the event listeners.
A detailed walkthrough of what happens internally is outside the scope of this article, but what basically happens is that the module classes found in Module.php are instantiated and various configuration methods are invoked. These methods could be for configuring the service manager, autoloading, controllers, controller plugins, routing and the view manager. The configuration for each module is merged into the main application configuration.
Autoloading
Zend Framework 2 makes use of namespaces which were introduced in PHP 5.3.0. However, namespaces do not remove the need to load necessary files, something that has previously been done with require() or include(). As a result, the framework includes autoloading functionality such that this happens automatically. The only thing module developers have to do is to specify how the autoloading should be done. This can be as simple as using Zend\Loader\StandardAutoloader. Within a module class, this can be configured like below.
public function getAutoloaderConfig() {
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
);
}
The module manager will invoke this method if the class either implements Zend\ModuleManager\Feature\AutoloaderProviderInterface or simply has a method with a name of getAutoloaderConfig(). In this case, the standard autoloader is simply given a path where the current namespace’s files can be found. The magic constants refer to the current namespace name and directory path, respectively.
What happens internally is that an autoload method is registered with PHP’s spl_autoload_register() method. This method adds the callable passed as a parameter to the autoload stack such that it is invoked if a class that has not been loaded is attempted to be used. Thus, autoloading lazily loads required files. This means that developers to not have to use require() or include() calls; rather, they can simply access classes directly and then the autoloading will take care of the rest.
During development, the standard autoloader is sufficient, but for a production environment where performance is more critical, the Zend\Loader\ClassMapAutoloader should be used. This approach can be configured like below.
public function getAutoloaderConfig() {
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php'
)
);
}
By convention, the ClassMapAutoloader should use a file named autoload_classmap.php. This file should return an array of class name and fully qualified file name pairs. This ensures that autoloading can be very efficient by simply doing an array lookup, which has an efficiency of O(1) in the Big O notation.
Multiple approaches can be used simultaneously; because the getAutoloaderConfig() method returns an array, these two approaches can be combined. A sensible approach would then be to first try to load a class with the efficient ClassMapAutoloader and as a fallback, attempt to load it with the less efficient StandardAutoloader. This way, an error can potentially be avoided if an entry is missing in the class map, for instance.
In addition to the class map file, two other files can also be added; autoload_function.php and autoload_register.php. The former should return a callback function which can be used together with spl_autoload_register() and may utilize the class map. The latter should register this callback function — typically with spl_autoload_register(). The reason for all of this is flexibility. By supplying these three files, autoloading can quickly and easily be configured, even if parts of the module is not used within a Zend Framework application — e.g. reusing the module layer in another context.
Here is what you will learn:
- Understand the theory of Zend Framework in details
- How to implement an enterprise-ready architecture
- Develop professional applications in Zend Framework
- Proficiently work with databases in Zend Framework
- ... and much more!