-
Modular Zend Framework Skeleton (Part 3: Modules)
Posted on June 6th, 2008 5 commentsThis article has been superseded by an updated article with new examples
Its taken a long time for me to back to this series as I’ve been swamped working on a large project. Fortunately the project heavily involved evolving my application skeleton which has actually graduated to a full blown Content Management System as I’d mentioned in a previous post. I was hesitant to do another one of these articles yet because of the rapid rate in which the skeleton was changing. I think the underlying foundation has stabilized enough to discuss it. While this thing is no longer a skeleton really, I am keeping the name of the series for SEO purposes.
Some things have changed since part 1 of the series but for the most part the folder structure is still the same. As my needs of the framework have become more sophisticated, my module architecture has needed to do the same. Rather than constructing modules as passive, non-intelligent folders, I’ve needed my modules to become something more interactive, meaning I want them to write code for me so I don’t have to. What does this mean you ask? Well its been a tedious task handling things like access control permissions, routes, etc, so I decided, why not make the modules dynamically construct those things. Well, I’m lying, its not 100% dynamic, I do have to write some code, but its actually more like defining a couple of arrays, and the underlying architecture takes care of the heavy lifting. So in order to make this machination work I’ve started by defining an interface which anything that calls itself an application module must implement if it wants a job in my skeleton. This simply defines some functions that a module must implement so we have information about what it has to offer.
Figure 1:
[The requested file http://misc.realmofzod.com/code/modular_zend_framework3/fp_application_module.php could not be found]
Most of the functions are for the sake of identification. getRoutes() and getPermissions() are the two useful ones, as they are a way for the module to report what valid routes it offers as well as what its access control needs are.
Figure 2:
[The requested file http://misc.realmofzod.com/code/modular_zend_framework3/blog_module.php could not be found]
Above you will see an example of what could pass as an application module. As you can see it identifies itself, provides some information about the author and defines all of its constraints to be reported back. Routes obviously is passed in a way that is easy to register with the front controller. Permissions are passed in a format that my ACL module expects which I will go over in a future post. The name of the class is very important as you will see when I demonstrate the module loader. It relies on a module to define this class a file of the same name. The class name of the module must be in all caps, the file name must be all lower case located in the lib folder of the module, and the entire module folder itself must be the same name. So for example, if you have a module called “Blog”, here is what your folder structure would look like:
–Folder structure for Blog module–
Figure 3:- app/
- blog/
- config/
- controllers/
- lib/
- blog.php
- views/
- blog/
Now you can change this to your tastes, this is just how I implemented it. So the next thing we need is some sort of “steward of the modules” if you will. Something that keeps track of all the loaded modules and facilitates inter-module communication. This is useful if one module relies on features provided by another module. Here is what such a beast would look like:
Figure 4:
[The requested file http://misc.realmofzod.com/code/modular_zend_framework3/app_module_broker.php could not be found]
It’s very simple really, it exists only to register modules and get registered modules. It’s an abstract class because I don’t ever instantiate it, its entirely static which makes it easier to access its members across the application since this class is accessible from anywhere.
If you read my first article in this series then you should already be familiar modules.php. As a refresher, it is one of many files that get loaded by another file called common.php. This is loaded by the bootstrap at each request. modules.php is responsible for finding and initializing all of the application modules. The interface above as well as the Module Broker class belong in this file as well as some other stuff to facilitate the process.
Figure 5:
[The requested file http://misc.realmofzod.com/code/modular_zend_framework3/modules.php could not be found]
In this file, the module folder is searched for subfolders which might contain application modules. Each one it finds gets handed off to the load_module() function which analyzes the folder for various module components. These components usually are config files, lib files, plugin files, etc. The requirements from the earlier article in this series haven’t changed much, it still requires a config folder, a controller folder and a views folder. In addition to the presence of those folders, a module now must have the module class in the lib folder as I demonstrated above.
Every module is treated equally and is loaded as they are found but you will probably see one exception to that. The Default module, which is the core application, is treated a little differently for a couple of reasons. One way that it is different is that the name of the module class is not ‘DEFAULT’ as you would expect. I would’ve preferred that it was but unfortunately default is actually a keyword in php so it was offlimits. The file name is still default.php as you would expect but the class is called ‘Main’. The module loader expects this and has a special condition when it sees the ‘default’ folder amidst the modules. Secondly, the default module is loaded last. The purpose of this is to allow for all other modules to be loaded as it is almost always the case that the main application will rely heavily on features provided by the other modules so we want to make sure that things don’t load out of order during the bootstrap process.
That’s the gist of it. Obviously there is a lot of room for optimisation here which I plan to implement in the next iteration. One way to boost performance is to cache this process so the loader doesn’t have to search through the file system for each request. Also I believe that all of the code in the load_module function should probably be moved into the application broker class but I just haven’t gotten to it yet.
5 responses to “Modular Zend Framework Skeleton (Part 3: Modules)”
-
Nice work. I haven’t seen many ZF developers share their approaches to developing a modular application structure.
Have you given further thought to the support and definition of module dependencies?
-
Module dependencies could be handled by adding an additional function on the module interface for retrieving dependencies either by name, name/version, or some unique identifier that it can use to search the module folder for the presence of said dependency. I leave this to the implementer.
-
[...] a little imagination we can make switching between implemenations dynamic. For those who read my earlier article on application skeletons, this can be accomplished by extending our application modules with getters for gateway objects. We [...]
-
[...] http://blog.realmofzod.com/2008/06/06/modular-zend-framework-skeleton-part-3-modules/ [...]
-
Hi there,
All the code is unfound.
See [The requested file http://misc.realmofzod.com/code/modular_zend_framework3/modules.php could not be found]best regards
David
Leave a reply
- app/


