Zend Framework Modules

Modular application setup has often been considered as little problematic in Zend Framework (ZF) when it comes to creating self-contained or isolated modules. The main reason is that every module specific resource is initiated with every request regardless if the module is requested or not. This article will go over some important points in Zend_Application component and present a solution to the problem of setting up module specific configurations in Zend Framework applications.

Zend_Application presents a great way of setting up the environment and handling resources. There is no doubt that it presents convenience and makes the development fun. It’s the backbone of the framework and acts as a manager of an application. Zend Framework project lead Matthew Weier O’Phinney posted a very informative article on Module Bootstraps. After going over Zend Framework manual and reading Matthew’s article, I came up with the following in regards To Zend Application and module setup :

1- Zend_Application bootstraps the entire application. This means default resources and all other module specific resources are initiated all together at the same time.
2- Since that happens prior to dispatch() and bootstrap does not know the request parameters, there’s no way to determine which module to go after.
3- In a large application, there will be module specific controller plugins, services, layouts, helpers, additional db resources, session management… etc. Current Zend_Application class simply does not present a way to deal with it depending on the modules.

There are a few ideas mentioned in Matthew’s article to tackle these issues. Going over the resources presented, it seems like it’s mostly agreed upon to find a resolution by creating a controller plugin. I also tried the recommended approach but never had the relief that it was doing what expected. Moreover, whatever I tried in terms of setting up module specific application with a controller plugin, I saw that it’s actually doing nothing more than what has already been done.

In my opinion, all the ideas I tested whether that would be mine or others do not provide any way of initializing module specific resources, but add more complexity instead of flexibility and simplicity. By adding another layer of configuration with a controller plugin, there will be one more dependency to maintain in the application. Besides, the application’s resources cannot be enhanced or changed by the module’s resources. As long as Zend_Application is wrapping the front controller before the controller starts the dispatch, and as long as the bootstrap does not know the request parameters there’s no way to implement a complete module specific configuration.


Well, how about getting rid of Zend_Application completely? Surely, that was not a problem.

// public/index.php
require_once 'Zend/Controller/Front.php';
$front = Zend_Controller_Front::getInstance();

Using Zend_Application has been a habit so giving up on it felt little weird I should say. So, I went back to pre Zend_Application era where you were alone with the almighty Front Controller. Actually the performance increase was HUGE simply because there were no resources initiated.

Then, I created a simple bootstrap class which only plays with the php.ini settings. I tested how to change the settings depending on the modules. I implemented the following idea, which worked perfectly.

Request -> Router -> Application Bootstrap -> Module -> Module Bootstrap

I applied the same logic to the following script which extends Zend_Application and allows self-contained modules. It might look like it creates an additional load to the default process but it does not. If you consider the fact that you only trigger the related module’s configuration instead of the entire application bootstrap, actually there’s much gain instead of loss.

Updated on 8/31/2010


require_once 'Zend/Application.php';

class My_App extends Zend_Application
     * Front Controller.
     * @var Zend_Controller_Front

    protected $_front;
     * Router
     * @var Zend_Controller_Router_Rewrite

    protected $_router;
     * Request.
     * @var Zend_Controller_Request_Http

    protected $_request;
     * Response.
     * @var Zend_Controller_Response_Http

    protected $_response;

     * Modules dir path.
     * @var string

    protected $_moduleDir;
     * Application path.
     * @var string

    protected $_appPath;

     * Sets up all the initial required pieces of the app.
     * @param string $environment
     * @param string $appPath
     * @param string $moduleDir

    public function __construct($environment,
                                $appPath = APPLICATION_PATH,
                                $moduleDir = 'modules')
        // set the environment
        $this->_environment = (string) $environment;
        // set the application path
        $this->_appPath = $appPath;
        // set the modules dir path
        $this->_moduleDir   = $this->_appPath .
                              DIRECTORY_SEPARATOR . $moduleDir;
        // initiate autoloader               
        require_once 'Zend/Loader/Autoloader.php';
        $this->_autoloader = Zend_Loader_Autoloader::getInstance();
        // set up module autoloading
        $this->_autoloader->pushAutoloader(array($this, 'moduleAutoload'));
        // set front controller
        $this->_front  = Zend_Controller_Front::getInstance();
        // add module directory
        // initiate request
        if($this->_request === null) {
            $this->_request = new Zend_Controller_Request_Http();
        // initiate response
        if($this->_response === null) {
            $this->_response = new Zend_Controller_Response_Http();
        // initiate router (Zend_Controller_Router_Rwrite)
        $this->_router = $this->_front->getRouter();
        // get application.ini options
        $appOptions = $this->_getApplicationOptions();
        // set routes in router from application.ini (if any)
        // update request with routes

        // get module options
        $moduleOptions = $this->_getModuleOptions();
        // merge application and module options into one array
        $options = $this->mergeOptions($appOptions, $moduleOptions);
        // set options
        // update front controller request
        // update front controller response
        // to be used in dispatch
     * Create options from application.ini.
     * @return array

    private function _getApplicationOptions()
        $appConfig = $this->_appPath . DIRECTORY_SEPARATOR .
                     'configs' . DIRECTORY_SEPARATOR .
        return $this->_loadConfig($appConfig);
     * Create requested module's options from the requested
     * module's module.ini.
     * Router resource can only be defined in application.ini.
     * @return array

    private function _getModuleOptions()
        $moduleName = $this->_request->getModuleName();
        $moduleDir  = $this->_moduleDir;
        $modConfig  = $moduleDir  . DIRECTORY_SEPARATOR .
                      $moduleName . DIRECTORY_SEPARATOR .
                      'configs'   . DIRECTORY_SEPARATOR . 'module.ini';

        $options = $this->_loadConfig($modConfig);
        if(isset($options['resources']['router'])) {
            throw new Exception ('You can only set routes in application.ini');
        return $options;

     * Add routes from options created from application.ini.
     * Router resource cannot be declared in module.ini.
     * @param array $options | from application.ini

    private function _addRoutesFromConfig($options)
        if (!isset($options['resources']['router']['routes'])) {
            $options['resources']['router']['routes'] = array();
        if (isset($options['resources']['router']['chainNameSeparator'])) {
        if (isset($options['resources']['router']['useRequestParametersAsGlobal'])) {
        $this->_router->addConfig(new Zend_Config($options['resources']['router']['routes']));
        // don't trigger Zend_Application_Resource_Router
     * Same route function in Zend_Controller_Front::dispatch().
     * It updates the request with routes.
     * @param Zend_Controller_Request_Abstract $request

    private function _route(Zend_Controller_Request_Abstract $request)
        try {
        }  catch (Exception $e) {
            if ($this->_front->throwExceptions()) {
                throw $e;
     * Instead of defining an autoloader for every module in
     * its corresponsing bootstrap, this take care of all the
     * autoloading for all the classes under modules. The only
     * thing is that the file names under modules need to be
     * exact in the class declaration.
     * Example:
     * application/modules/bugs/models/Tracker.php
     * So the Tracker.php will have the following class:
     * class Bugs_Models_Tracker
     * {
     *      // code
     * }
     * You can call this class:
     * $tracker = new Bugs_Models_Tracker();
     * This can also be achieved within this function with
     * a closure but then autoload won't work for any PHP
     * version lower than PHP 5.3.
     * private function _moduleAutoload()
     * {
     *      $load = function($class) {
     *          $file = $this->_moduleDir . DIRECTORY_SEPARATOR .
     *              str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
     *          require $file;
     *      };
     *      $this->getAutoloader()->pushAutoloader($load);
     * }
     *  Then in the constructor of this class you can call this function as
     *  $this->_moduleAutoload();

    public function moduleAutoload($class)
        $file = $this->_moduleDir . DIRECTORY_SEPARATOR .
                     str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
        require $file;

Now we need to make a change in the Front Controller’s dispatch() method to prevent double routing. We already processed routing in My_App::_route() method. So we need to remove it from the dispatch() method. One important thing to notice is that since the routing has already been completed, there’s no use for the routeStartUp() controller plugin call in Front Controller’s dispatch(). Even if a controller plugin with routeStartup() is registered with the Front Controller, it will perform the same as a routeShutdown() because the route has already been completed.

In the current version of My_App, if a specific routeStartup() plugin want to be registered, then My_App::__construct() has to be modified to run these plugins before the routing occurs in My_App::_route() method. A better way would be to separate the method calls in My_App::__construct() to small chunks of private methods in My_App and configure it to run routeStartup() plugin before the routing occurs. I will leave that up to the developer since routeStartup() is a very specialized plugin which actually can be done in many other ways as well and depends on the use case. Currently, Router resource can be defined in application.ini.


public function dispatch()
// remove the following in dispatch()
// you can remove routeStartup() as well if you'd like
// $this->_plugins->routeStartup($this->_request);
try {
     }  catch (Exception $e) {
        if ($this->throwExceptions()) {
            throw $e;

That’s it. Let’s see the public/index.php


    define('APPLICATION_ENV', 'development');
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
    PATH_SEPARATOR, array(realpath(APPLICATION_PATH . '/../library'),

require_once 'My/App.php';
$application = new My_App(APPLICATION_ENV);

Let’s look at the directory structure.

Directory Structure

Now remember that the module.ini merges with application.ini resources. As you see above, there is no Bootstrap class specified in application.ini because module.ini will decide where its Bootstrap class is and its name. Since module is independent, all the module resources need to be declared in the module.ini. Below you will see I declared a layout path for Test module’s layout, which includes a simple background color (gray). There’s no layout defined in default module’s ini. Additionally, I created a Test controller plugin and registered it with Test module only. Default module has no plugin. More on this subject in a little while.


bootstrap.path = APPLICATION_PATH "/modules/test/Bootstrap.php"
bootstrap.class = "Test_Bootstrap"
resources.layout.layoutPath = APPLICATION_PATH "/modules/test/layouts/scripts"
resources.frontcontroller.plugins.test = "My_Test"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

Here’s My_Test controller plugin. It’s only registered with the test module.


class My_Test extends Zend_Controller_Plugin_Abstract
    public function routeStartup(Zend_Controller_Request_Abstract $request)

Here’s one of the Bootstrap files in the module. The module bootstrap does not extend Zend_Application_Module_Bootstrap. It’s like the main bootstrap file, it extends Zend_Application_Bootstrap_Bootstrap.


class Test_Bootstrap extends Zend_Application_Bootstrap_Bootstrap


Let’s pull up the page. http://localhost/test


See the var_dump() above coming from the My_Test plugin. It says “_dispatched: false” and you can see all the request parameters before the routeStartup(). The only resource that cannot be initiated in module.ini is the Router resource. If you define routes in module.ini, then an Exception will be thrown. The reasoning behind this is that if you’re defining routes, this is an application wide setting. So it has to be done in application.ini. Keep your application wide settings in application.ini and module settings in module.ini. It’s straightforward.

The restriction I see is the configuration file types because currently they are fixed in My_App to .ini . Is it possible to extend to cover other ones like xml, yaml…? Sure it is. Again, this depends on the use case and I will leave that up to the developer. I use .ini because it has a much cleaner look and easier for me. If you would like to have more than one configuration file under /configs directory, then a method can be created in My_App to iterate through the files under /configs directory and these can also be added to the options.



My_App creates isolated modules for your application and it can be modified depending on the application needs. It presents an alternative to the conventional Zend Framework’s module based application setup. The best part of My_App is that we do not have to rely on application wide settings and it does not present a dependency to maintain. We can override the application.ini settings in the modules if we want to. We can declare any resource in application.ini and as long as module.ini does not override it, it will be available to the requested modules. A lot of possibilities come into play, which I will try to cover it in another post.

Your thoughts?

UPDATE: This post was formerly known as Module Based Configuration in ZF – Part II. It was confusing having 2 articles for the same subject. Combined both articles, redirected Part I to this post and changed the title to Zend Framework Modules.


  • [...] Omercan Sebboy hat den zweiten Teil seines Tutorials für die Modulbasierte Konfiguration einer Zend Framework Anwendung veröffentlicht. [...]

  • dev
    August 25th, 2010 at 7:47 pm

    Hi, thank you for this follow up!

    So far, I tried to rebuild it, but unfortunally, there are some errors:

    Fatal error: Uncaught exception ‘Zend_Application_Bootstrap_Exception’ with message ‘No default controller directory registered with front controller’ in D:\www\test\web\library\Zend\Application\Bootstrap\Bootstrap.php on line 91

    Zend_Application_Bootstrap_Exception: No default controller directory registered with front controller in D:\www\test\web\library\Zend\Application\Bootstrap\Bootstrap.php on line 91

    I don’t kow why Zend Application want to have default controller directory. Any idea?
    I am working on that.

  • osebboy
    August 25th, 2010 at 8:22 pm

    It’s highly possible the following line in your code does not provide the correct path to the module’s directory in My_App::construct()
    { ….

    After this, default controller directory is under …application/modules/default/controllers

    Make sure your application.ini does not have default settings.

  • dev
    August 26th, 2010 at 9:23 pm


    got it.
    sorry, was my mistake.

    i had a break of several months with zend framework …

    your solution is awesome.

  • osebboy
    August 27th, 2010 at 1:36 pm

    I needed to re-factor a few things in the code… namely, Router resource and autoloading for the modules.

    I will update the code in a while…. or I might do a “part 3″ with a little more explanation for the folks who want to know more about modular applications and its benefits.

  • Francesco
    September 17th, 2010 at 2:18 am

    hello, congratulations for the solution.

    I’m reading a lot on the internet about an optimal solution for a modular application with Zend Framework. Starting from an article by Matthew Weier O’Phinney.

    Or other implementations like this:

    Your solution seems more powerful but a bit more invasive.

    It would be much appreciated if you put a zip file with the folder structure and files (eg with a default module and a module test) so that we can test.

    I hope for a third party with some more explanation about the structure, work-flow, etc.??
    What do you mean with “A lot of possibilities come into play?

    Thank you.

  • osebboy
    September 17th, 2010 at 3:19 am

    Hi Francesco,
    I would appreciate if you can elaborate on “invasive” so I can better understand your concern.

    I will put the code in a zip file as soon as I find some time.

    What do I mean by possibilities? I believe this by itself deserves a few more posts about the subject but shortly, with this structure, you can completely isolate a module from others. Actually, you can enforce that by removing My_App::moduleAutoload($class) method and adding autoload for modules in their own Bootstrap, so you can’t call one module’s class from other modules. Think about an application where each module is self-sufficient. Then you can just connect to the application through the Bootstrap. This leads to a great plugin based application with reusable components. If more than 1 module need to work together for a certain part of an application, then you can define that in the related modules’ Bootstrap and control all the dependencies between the modules. This stops arbitrary method calling between modules which leads to maintainable code.

  • Francesco
    September 17th, 2010 at 10:49 am

    I knew the advantages about of a modular structure. I have been reading many suggestions and discussions on how to approach, precisely because they understand the benefits.

    about the invasiveness,
    I refer to fact that your approach involves a class that extends Zend_Application and a change in the Front Controller’s dispatch() method: two key components of the Framework.
    But this isn’t a problem just a fact.

    As say Matthew Weier O’Phinney “The true problem is that modules are really second-class citizens in ZF currently.”

    So i continue to be very interested in this solution if it facilitates the use of modules as independent components of the application and not as mere parts of the application divided into folders.

  • osebboy
    September 17th, 2010 at 4:08 pm

    As I tried to explain in my post, the problem I saw with other implementations including the controller plugins require a lot more customization in the code without actually separating modules from each other. My_App just changes the sequence of MVC flow treating a module as a separate entity which comes to your last statement.

  • osebboy
    September 17th, 2010 at 7:29 pm

    Source download has been added. Right above the Conclusion.

    There is “Bugs” module instead of “Test”. That’s the only difference.

  • LowTower
    October 11th, 2010 at 9:55 am

    Hey Osebboy,

    with the current implementation (from Your download) the main Bootstrap in /application/Bootstrap.php is not run.

    In my opinion, it should be run before the module’s Bootstrap is run.


  • osebboy
    October 11th, 2010 at 11:13 am

    Correct. It’s left untouched because the actual module configuration is carried over to modules’ bootstrap. It can be added to the flow if you need to use it in your app.

  • Grégoire Lafortune
    February 8th, 2011 at 8:48 pm

    I agree to say that it opens up lot of possibilities, that’s very nice work!

  • Cristian
    March 7th, 2011 at 7:51 am

    Thanks man!!
    This was the lead I needed.
    Following your example I extended Zend_Application in such a was that module.ini settings override application.ini.

    It works great! Just need to test it more.
    Since I moved to php from java I forgot about inheritance and how powerfull it is.

    Best of luck and thanks again!

  • Argo
    March 7th, 2011 at 9:54 pm

    You could do wonders starting from this. Nice one.

    There just one problem, at least for me. The fact that it requires to change zend library.
    There are situation were you can’t do that, say if you have a common library for several projects.

    Is there a way to remove the double route without changing the library directly?
    How bad is a double route performance wise? I hope it’s the only issue…

  • osebboy
    March 8th, 2011 at 1:16 am

    The whole idea behind My_App’s isolated module setup is based on getting the Request first, configuring the routes second and then initializing the other components. So, in this sequence, Zend_Controller_Front::dispatch() is run after the routes are configured in My_App. So, that’s the only way it can be done with My_App.

    Of course, the MVC layer of the framework can be rewritten which I did… but I haven’t had a chance to test it all the way. I think I will release it all at one point… when I can find some time.

  • dskanth
    March 30th, 2011 at 9:55 pm

    Hi, this architecture works great…. i just want to know how to implement the regex routing in my application and where do i define the routes.

  • osebboy
    March 31st, 2011 at 12:08 am

    In application.ini. How to do it? You can learn that from Zend Framework documentation.

  • Jatin
    May 26th, 2011 at 10:34 am

    HI osebboy!

    Thanks for the lovely tutorial.

    I was able to set up the complete environment but stuck at one point.

    In my case I want to write common models which will be accessible by all other modules.

    My plan is to put the models in default/models folder which will be accessible by other modules.

    What should I do?

  • osebboy
    May 26th, 2011 at 3:22 pm

    “Writing common models” does not seem to be open and clear. What I understand from your statement is that you are trying to create a module which can be used in other modules. There might be services, plug-ins as well as some model classes to be reused. When you approach it this way instead of limiting yourself to a module’s ‘models’ only, you would have a much clear picture.

    I received so many emails in regards to how to create modules that can be reused in other modules.

    There are a few ways to solve this matter. My favorite has always been defining my dependencies through an interface where I can not only keep the dependencies in check, but I also state clear definitions how to use the dependencies. The best way to declare your dependencies and introduce them to your application is through the module’s bootstrap.

    So, to answer your question, 1- Create your module 2- Create your services(models, events, triggers…) 3- Define an interface(API) to utilize these services in its Bootstrap, which can be called from other modules. Use that API only to communicate at the modular level. One common mistake most developers do is to just arbitrarily instantiate a class in another module without any precondition because it is easy, but it is very wrong, a recipe to spaghetti code.

    So, in this type of set up, you are not instantiating the classes in other modules directly but through their defined members in that module’s Bootstrap. If you are talking about creating something like… CRUD operations which can be utilized in all of your models, then your focus should not be on this modular setup, but more on the domain layer of your app. Hope this answers your question.

  • Jatin
    May 30th, 2011 at 5:24 am

    Thx for your prompt response dude.

    Ya, I want to write common models which can be used by every other modules.

    I am kinda newbie in Zend, so was not able to interpret your words completely :-( .

    If you can post a sample code (I know its irritating) then it will complete your modular setup with Zend.

    Many thanks in advance bro.

  • osebboy
    May 30th, 2011 at 2:07 pm

    As I tried to explain, your main problem is not related to Zend Framework’s modules to start with. Take a look at database design patterns, or jump into Doctrine2. See what it can offer you. Then you will have an idea what you need to do.

  • David Johns
    September 9th, 2011 at 3:17 pm

    This is great work. I have worked with the Zend Framework for a number of years and it calls out for modularization; as a site with 20 controllers can become pretty hard to maintain!

    I have one issue with your download Fatal error: Undefined class constant ‘EXCEPTION_NO_ROUTE’ called in Error Handler. I have checked that this constant is defined. Any ideas? Thanks

  • Edward Mungai
    February 21st, 2012 at 8:33 am

    Simply genious! I was working on a regionalwide erp system and had no idea how to separate the data from the different country site. Your lib came to my rescue. I have no words to express my gratitude. *bows*

  • Andrew
    May 10th, 2012 at 6:03 am

    Your article was a life saver! I have been trying to get Zend to behave this way for some time now and your solution solved the problem. I like the idea where you suggested having an API to handle shared models, plugins, etc.

    But i’m facing a problem now. I’ve managed to set everything up as per your example but was not able to get the var_dump output. Checked and double check everything that i might have missed but still can’t get it to show up.

    Apart from that everything works. Modules.ini overwrites Application.ini, bootstrapping, etc.

  • Sapher
    September 25th, 2012 at 3:21 pm

    So there’s no way to run application/Bootstrap.php? I got something like this in my application/Bootstrap.php

    $api_host = new Zend_Controller_Router_Route_Hostname(

    $zend = new Zend_Rest_Route(
    ‘module’ => ‘api’

    $chained_api_route = new Zend_Controller_Router_Route_Chain();
    $frontController->getRouter()->addRoute(‘api’, $chained_api_route);

    This work perfectly, but i can’t find a way to translate it and put it in application.ini

  • osebboy
    September 25th, 2012 at 6:53 pm

    application/Bootstrap.php is not configured to run due modular approach. You can add the route in the application.ini. Or, if there’s any script to be executed before the application reaches the module’s Bootstrap, then you can add it to MyApp class to run before the module routing. It’s pretty simple.

  • Sapher
    September 26th, 2012 at 2:11 am

    Thanks for the reply. I can manage to do what I wanted to do. I climbed on the roof top and I yelled your name ^^. Thanks a lot

  • Altaf Hussain
    March 3rd, 2013 at 7:55 am

    Thank you for this good post. I am trying to use it, but i got a problem with it, which is i cant connect to db. I am making the db connection is below in my Application/bootstrap.php (It was before i tried to use your changes for the modular app.

    protected function _initDB()

    $resource = $this->getPluginResource(‘db’);

    $db = $resource->getDbAdapter();

    Zend_Registry::set(“db”, $db);


    As for your application, this bootstrap file is ignored, so where i can place this code? I tried to place it in My_App class, but still i got the error like

    ” Call to a member function select() on a non-object in ”

    Can you please give me some sample code, which i can use some where to make connection to the database and get the adapter ?

    Looking forward for your quick response.

    Thank you

  • [...] http://www.osebboy.com/blog/zend-framework-modules/ This entry was posted in PHP on May 28, 2012 by admin. [...]