ZF2 Cache #2: Generating class and template maps
Introduction
This is the second post in a series of three demonstrating the caching abilities of ZF2. In the first post, we saw how the configuration files that contain important information such as routes and templates can all be merged into one configuration tree and saved for future lookup. We also briefly seen an array map in action which was used for locating a module's class file. This mapping technique will be the main subject of this tutorial where we will be generating array maps for our module's classes and templates.
The class map itself
To understand the function of the class map, first, take a look at one of mine for my Blog module:
return array( 'Blog\Module' => __DIR__ . '/Module.php', 'Blog\Controller\PostController' => __DIR__ . '/src/Blog/Controller/PostController.php', 'Blog\Controller\PageController' => __DIR__ . '/src/Blog/Controller/PageController.php', 'Blog\Controller\IndexController' => __DIR__ . '/src/Blog/Controller/IndexController.php', 'Blog\Controller\CategoryController' => __DIR__ . '/src/Blog/Controller/CategoryController.php', 'Blog\View\Helper\RecentPosts' => __DIR__ . '/src/Blog/View/Helper/RecentPosts.php', 'Blog\View\Helper\Menu' => __DIR__ . '/src/Blog/View/Helper/Menu.php', 'Blog\View\Helper\CategoryMenu' => __DIR__ . '/src/Blog/View/Helper/CategoryMenu.php', 'Blog\View\Helper\PostCategory' => __DIR__ . '/src/Blog/View/Helper/PostCategory.php', );
As you can see above, my class map contains controllers (as well as other classes used by the Blog module) with their respective filesystem path. This class map file provides a quick lookup when classes are loaded. Instead of relying on the StandardAutloader to load the class which involves unnecessary filesystem operations, ZF2 will refer to the class map to locate and instantiate the class.
Creating your first class map
Thankfully, the developers of the framework have provided a neat little script that will generate your class map file automatically. Although it is possible to manually create the map, it could take a while doing so especially if your module has a load of service configured classes. It is also very error prone...
To execute this map generator script, you must first open a terminal window if you're on Linux/Unix or, a command prompt window if you're on Windows.
With your command line now open, do the following:
- Browse to the root folder of the module you want to generate a class map for. e.g. cd /var/www/zf2/module/Application
- Run the following command: php ../../vendor/zendframework/zendframework/bin/classmap_generator.php
Your command window should look like mine:
To confirm the creation of your new class map file. Browse to the folder of the module you created the class map for e.g. module/Application. You should see the new file named "autoload_classmap.php".
Using your new classmap
In order for your application to utilise the class map you just created, we need to make a change to module's "Module.php" file. If you open the file, you will see a method called "getAutoloaderConfig". This method tells the module when it's loaded, to locate classes using the StandardAutoloader. We want our module to use the new class map file we just created. To do so, simply add this code above the StandardAutoloader.
'Zend\Loader\ClassMapAutoloader' => array( __DIR__ . '/autoload_classmap.php', ),
The method should now look like this with our new code:
public function getAutoloaderConfig() { return array( 'Zend\Loader\ClassMapAutoloader' => array( __DIR__ . '/autoload_classmap.php', ), 'Zend\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), ), ); }
Creating the template map
Creating your template map is just a simple as your class map. It follows the exact same sequence.
- Browse to the root of your module folder e.g. cd /var/www/zf2/module/Application
- Run the following command: php ../../vendor/zendframework/zendframework/bin/templatemap_generator.php
It's is as easy as that. You should now have a file called "template_map.php". In this file you will see an array of template aliases and the filesystem path to their file. This mapping of template files again, helps reduce the heavy lifting the application does when loading templates for your views.
Using your template map
Like the class map, we need to tell our module about our new template map file. To do this, open the module's "module.config.php" file and go to the node called "view_manager". You can delete array called "template_map" as we will be replacing it with a newer version which loads our template_map.php file. It should look like this:
'view_manager' => array( 'display_not_found_reason' => false, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_path_stack' => array( __DIR__ . '/../view', ), 'template_map' => include __DIR__ . '/../template_map.php', ),
Finishing up
If you followed the instructions above, you should now have a module that will function much quicker than before. You can also apply these features to other modules that you may have in your application.
In the next post, I will be demonstrating Zend's full-page caching features where we will be caching pages that rely on multiple database calls to build it.