Zend Framework Modular Structure
Following on from an earlier post about Zend Framework Structure, I wanted a more modular approach for a set of tools I’m working on for some internal work. It is a collection of applications, and I wanted each application to be split into a seperate folder, with it’s own controllers, models, layouts, forms and views.
However, I also wanted to share components across all of the applications; and only have one instance of Zend. For example, the login script – once logged into the system, you could access all of the mini applications, so they would need to be able to check login etc without duplicating all the code.
You can read more about how Zend see a modular implementation in the manual here: http://framework.zend.com/manual/. This article should hopefully provide you with the source and knowledge to start yourselves with a modular Zend Framework outline.
I could also see this approach definitely working for larger scale applications; when you want a more modular structure to your application. There are a few points that we need to be aware of when moving to a modular system.
Routes
Routes are slightly more elaborate when using modules. We use a seperate routes file rather than relying on Zend’s auto fashioned URLs, and you need to make sure that the module is referenced in the call.
Usually, you could create a route thus:
$route['index'] = new Zend_Controller_Router_Route( '', array('controller' => 'index', 'action' => 'index')); |
With modules, we need to go a little further, thus:
$route['index'] = new Zend_Controller_Router_Route( '', array('controller' => 'index', 'action' => 'index', 'module' => 'default')); |
Autoloading
One thing I didn’t want to lose was the Autoloading feature of the Zend Framework which comes in so very handy.
Autoloading allows you to reference a class by structuring its name, similar to its folder structure.
A quick example:
/
/application/
/controllers/
blogController.php
/models/
blog.php |
So, say we want to instantiate the blog class from blog.php in the blog controller blogController.php. Without autoloading, our controller class would have to look like this:
<?php require_once "/models/blog.php"; class BlogController { public function __construct() { $blog = new Blog(); } } ?> |
In this instance, the blog model class would be called simply Blog. Notice the need to include/require the file somehow at the top of the controller. This could get very messy, very quickly if your controller offers all sorts of functionality. With autoloading, we simply rename the blog model class to Model_Blog, and we don’t need to ‘include’ the blog model, Zend (and our app) already knows about it. This means that we can then use the following:
<?php class BlogController { public function __construct() { $blog = new Model_Blog(); } } ?> |
Autoloading makes our code easier to read, and easier to follow. The blog class could be referenced in any number of included files, but using autoloading, we have a pretty good idea of where to look.
Autoloading is definitely a feature we don’t want to lose when we move to a modular structure, so we need to make sure that we tell Zend to keep this, and let it know about the new structure.
Structure
The stucture we’re aiming towards is something like this:
/
application/
configs/
modules/
default/
controllers/
layouts/
views/
forms/
blog/
controllers/
layouts/
views/
forms/
news/
controllers/
layouts/
views/
forms/
library/
public/
css/
js/
images/
uploads/ |
We’re probably going to alter this structure for something that matches our application better when in development, but for now, it provides a good overview.
Set Up
So that we can use all of the exciting automagic that Zend provides, we need to add a couple of extra things into our application that aren’t usually required when building a more traditional, flat structure.
Bootstraps
For autoloading to work in a modular structure, we need to include a bootstrap.php file in every module we create. This should be simple, and blank, except for a bootstrap class constuction.
Our default bootstrap would look like this:
<?php class Default_Bootstrap extends Zend_Application_Module_Bootstrap { } ?> |
We’re extending the main bootstrap for the site – so this should still be in place (in the main application folder in our case).
Autoloading
Class names should now follow this structure:
<?php class Test_IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { $blog = new Test_Model_Blog(); } } ?> |
Letting Zend know about your structure
As mentioned in the opening paragraph, Zend supports modules. Usually, you’d need to make Zend aware of the controller, models etc directories explicitly when using a modular structure, but you can just tell Zend your modules folder, and let it sort out the rest.
In your application.ini file, add the following:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" resources.modules[] = "" |
This tells the front controller where your module directory is located and clears the modules loaded.
What about layouts?
If you wanted to store layouts all in once place (which seems sensible if you’re controlling the whole frontend of your site), then you can edit your application.ini with something like the following:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts" resources.layout.layout = "layout" |
By now, you have a fully functioning Zend Framework structure based on a modular design. If you’re still struggling, try the download below. It’s only half of an example as I’ve not had the chance to build a properly working test case for the structure outside of the application I’ve built. However, it should point you in the right direction! You’ll need to grab yourself a copy of the Zend framework and stick it in the library/Zend/ folder.
Download the Zend Framework structure
If you have any thoughts on this before we get comments sorted, find me on Twitter – @douglasradburn
Comments
Latest from B3Labs
- Another milestone reached for Branded3 as it’s acquired by the
St Ives Group - The latest media consumer findings & what they mean for digital marketers
- Talk to Branded3 at @BuyYorkshire in Leeds next week!
Latest from Blogstorm
- Early thoughts on Penguin 2.0
- 5 myths about manual penalty recovery
- Google gets more aggressive with link devaluation


