I am working on a small API for bluesignal and i wanted a modular architecture. I have done this before using the Zend Framework. But this time i wanted a bit more control while loading the modules. And adding a Bootstrap class would seem like a good option. The only example i could find involved loading all bootstraps on every request. Which doesn’t seem like a good idea. So after reading through the Manual and some blog posts. I decided to give it s shot my self.
The structure i want looks like this.
The application.ini file has the following contents:
includePaths.library = APPLICATION_PATH “/../library”
bootstrap.path = APPLICATION_PATH “/Bootstrap.php”
bootstrap.class = “Bootstrap”
resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
resources.modules[] = “default”
resources.modules[] = “admin”
includePaths
This sets the applications local library location. Any shared code for this application goes here.
bootstrap.path & class
Define the location and type of the Bootstrap class.
resources
Define the modules location and create a list of modules.
The main Bootstrap class
application/Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
Load the config parameters for this application and set some debugging settings if needed.
protected function _initConfiguration()
{
$app = $this->getApplication();
$config = $app->getOptions();
if (APPLICATION_ENV == 'development') {
error_reporting(E_ALL & E_STRICT);
if (isset($config['phpsettings'])) {
foreach ($config['phpsettings'] as $setting => $value) {
ini_set($setting, $value);
}
}
}
}
We need autoloading here because we are using a class from the application library. Right now this causes a problem. A notice is thrown
Warning: include_once(FrontController.php) [function.include-once]: failed to open stream: No such file or directory in Zend/Loader.php on line 147
The application responds fine. And this problem seems to be a recurring issue (ZF-7224, ZF-7550) for the framework. Until now i have not find a graceful fix for this. besides a small patch reversion.
protected function _initAutoload()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $autoloader;
}
Setup the controller to register the Bluess_Modules_Loader plug-in. And set the prefixDefaultModule parameter so we can prefix the default module controllers as well. Just for the sake of consistency. The Bluess_ namespace is part of my API. And can be changed at will.
protected function _initController()
{
$this->bootstrap('FrontController');
$controller = $this->getResource('FrontController');
$modules = $controller->getControllerDirectory();
$controller->setParam('prefixDefaultModule', true);
$controller->registerPlugin(
new Bluess_Modules_Loader($modules)
);
return $controller;
}
Now the last method. which is a bit weird. And i am probably missing a key factor here. But if this method resource is not declared only the default module functions. When declared empty all modules function as they should. This would indicate that this method could be used to load the modules. But i haven’t found a way to achieve this yet. Except for loading all modules in a row. Which makes no sense for this purpose. So we leave it empty.
protected function _initModules()
{
// Call to prevent ZF from loading all modules
}
The most important part here is the controller plug-in. This will be the place where module bootstraps are called from.
application/../library/Bluess/Modules/Loader.php
class Bluess_Modules_Loader extends Zend_Controller_Plugin_Abstract
{
protected $_modules;
Setup the plug-in by passing the applications module list.
public function __construct(array $modulesList)
{
$this->_modules = $modulesList;
}
The dispatchLoopStartup method will be called on every request and will do the magic. Based on the current module name we create a new Zend_Application with the current modules config file module.ini. And we bootstrap it.
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$module = $request->getModuleName();
if (!isset($this->_modules[$module])) {
throw new Exception("Module does not exist!");
}
$bootstrapPath = $this->_modules[$module];
$bootstrapFile = dirname($bootstrapPath) . '/Bootstrap.php';
$class = ucfirst($module) . '_Bootstrap';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/modules/' . $module . '/configs/module.ini'
);
if (Zend_Loader::loadFile('Bootstrap.php', dirname($bootstrapPath))
&& class_exists($class)) {
$bootstrap = new $class($application);
$bootstrap->bootstrap();
}
}
}
Now setup the default module. Once this is done it’s a nice example for further modules. Make sure the module has it’s own layout set.
application/modules/default/configs/module.ini
default.resources.layout.layout = “default”
default.resources.layout.layoutPath = APPLICATION_PATH “/modules/default/layout”
Setup the modules bootstrap and use it to set the modules model location.
application/modules/default/Bootstrap.php
class Default_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected $_moduleName = 'default';
protected function _initConfiguration()
{
$options = $this->getApplication()->getOptions();
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/modules/' . $this->_moduleName . '/models'),
get_include_path(),
)));
return $options;
}
}
That’s all. Now make sure your layout is set correctly and the controllers are prefixed
application/modules/default/layout/default.phtml
echo $this->layout()->content;
application/modules/default/controllers/IndexController.php
class Default_IndexController extends Zend_Controller_Action
{
It took me a while to get this working like i had it in my mind. But it’s going the right way. If your interested in a working copy. You can download one here.
UPDATE
Matthew has a nice post about some do’s and don’ts concerning module based applications




Thijs Lensselink is a PHP developer, consultant and all out open source enthusiast.
He has over 12+ years of experience in building and maintaining web applications mostly
on linux/Unix/BSD platforms. Besides a full time job he does freelance work with his ...
[...] Read this article: Zend Framework Bootstrapping Modules at Web Development and stuff… [...]
Zend Framework Bootstrapping Modules at Web Development and stuff… | Coder Online
6 Feb 10 at 23:41
[...] Zend Framework Bootstrapping Modules at Web Development and stuff… [...]
Drupal Unsupported Database Error (my database IS supported)? | Drupal Powered By
23 Feb 10 at 05:48
Hi, I tried implementing it but its throwing an error, it can not find application.php hence giving “Fatal error: Class ‘Zend_Application’ not found”
Mohammad Azhar
9 Mar 10 at 11:39
What version of ZF are you using?
Thijs Lensselink
9 Mar 10 at 19:01
Hey Thijs , I found it the easiest way to achieve module based bootstrapping
This code worked absolutely fine with version 1.8.4 but i want to use it for the latest version like 1.10….
Hence we are not having ‘Application.php’ here.
can you please help me out ?
Thanks in advance!!!
Mohammad Azhar
10 Mar 10 at 07:58
Hello Mohammad, I’ve checked the documentation. and Zend_Application should still be available in 1.10. I don’t know if my solution works for 1.10 though. I will take a look at it this evening.
Thijs Lensselink
10 Mar 10 at 08:35
Thanks for the quick reply.
:)
Mohammad Azhar
10 Mar 10 at 08:51
Hey Thijs,
Its Working fine with the other Versions as well.
my bad!!! i was referring the wrong library.
Thanks, i found it really useful.
Mohammad Azhar
10 Mar 10 at 14:41
Great to see it worked out. And good that my post could be of some value. Happy hacking :)
Thijs Lensselink
10 Mar 10 at 18:37
Hi,I tried implementing it . But I not familiar with Zend_Acl and Zend_Auth integration checking, please gets advice, thanks!
Hr
11 May 10 at 11:09
$this->getInvokeArgs() not eligible configuration(application.ini) parameters ,why?
Hr
20 May 10 at 15:40
Hey Thijs,
can you please tell me how are we going to handle Exceptions here, coz handling exception (providing try catch) in Bootstrap will be a good practice and will remove our overhead of doing it at all places.
Mohammad Azhar
3 Sep 10 at 07:22
Mohammed,
We can catch Exceptions in the module loader plugin. So we can catch Exceptions locally in the module bootstraps and re-throw them.
Thijs Lensselink
5 Sep 10 at 13:06
Hi Thijs, the plugin works for me perfectly, I have the module “default”, “admin” and “personal.” All is well.
The problem I have is that in the module “admin” in the “configs” I created the file “routes.ini” and I want to load it from “admin / Bootstrap.php” but I load my routes.
“admin/Bootstrap.php”
=====================
// This is my function
protected function _initRoutes()
{ $frontController=Zend_Controller_Front::getInstance();
$router=$frontController->getRouter();
$router->addConfig(new Zend_Config_Ini(APPLICATION_PATH.”/modules/admin/configs/routes.ini”, APPLICATION_ENV), “routes”);
}
“admin/configs/routes.ini”
==========================
[production]
routes.adminlogout.type = “Zend_Controller_Router_Route_Regex”
routes.adminlogout.route = “admin/(logout)”
routes.adminlogout.defaults.module = “admin”
routes.adminlogout.defaults.controller = “index”
routes.adminlogout.defaults.action = “logout”
I hope you can give me help with this, thanks.
victor
6 Oct 10 at 01:43
Hello Victor,
i didn’t use the module based structure posted here for a while. But i remembered i ran into the same issue some while back. So i had to take a look at what the code was trying to do.
I wrote the module_loader plugin so had a bit more control over the module loading process. This is causing problems. It’s not possible to set the routing since the frontController is already instantiated.
The solution is pretty simple though.
In the application bootstrap comment out the initModules() method
//protected function _initModules() { }
Also comment out the module_loader plugin inside _initController()
//$controller->registerPlugin(
//new Bluess_Modules_Loader($modules)
//);
Now you can add routes to your module bootstraps like you are used to.
protected function _initRoutes()
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$foo = new Zend_Controller_Router_Route(
‘foo/:test’,
array (
‘module’ => ‘default’,
‘controller’ => ‘index’,
‘action’ => ‘index’
)
);
$router->addRoute(‘foo’, $foo);
}
Thijs Lensselink
6 Oct 10 at 10:26
Hi sir,
Sir i done what you had mention above steps it coming but it is coming as blank page sir so please i don know please can you tell me about this sir please
Thanks
Bakkesh
Bakkesh
10 Dec 10 at 14:18
Hee,
The download link is broken, can you please fix it
Silverbullet
12 Mar 11 at 21:31
Seems i forgot some files when i moved the site. Thanks for the heads up. The downloads should function properly again.
Thijs Lensselink
13 Mar 11 at 12:12
Hi,
I’m totally new to ZF. I tried to setup your example it works fine but still having a small problem. If you set error_reporting(E_ALL | E_STRICT); in your application/Bootstrap.php php warning message is displayed.
Warning: include_once(FrontController.php) [function.include-once]: failed to open stream: No such file or directory in C:\wamp\www\rnd\library\Zend\Loader.php on line 146
Warning: include_once() [function.include]: Failed opening ‘FrontController.php’ for inclusion (include_path=’C:\wamp\www\rnd\public/../application/../library;C:\wamp\www\rnd\library;.;c:\php\includes;C:\wamp\www\common\’) in C:\wamp\www\rnd\library\Zend\Loader.php on line 146
I’m using the latest version of ZF. Any idea to solve it?
Hans
28 Apr 11 at 10:17
Hey Hans,
This is quite an old post. This could be an autoloader issue. It looks like the core ZF files are not found. But this might be caused by changes to ZF
since i write the post. I will have a look at the code later today. But can’t promise anything.. Take a look on Matthew’s site for more inspiration.
Thijs Lensselink
28 Apr 11 at 12:38
Moin,
thanks for this post – though it’s old it was the only one who really helped me setting up a module structure. The only point I was struggeling with for hours and hours: Autoloader didn’t found the classes in forms and/or models etc. Solution: Uppercase the module name in the module’s Bootstrap file.
sonja
2 Aug 11 at 09:04
[...] http://lenss.nl/2010/02/zend-framework-bootstrapping-modules/ [...]
Zend Framework « Blog Ramon RDM
18 Jan 12 at 03:16
Hi,
Thanks for the tutorial and the sources.
One things which doesn’t work using your solution and my architecture is when you need to load a class which is in another module.
I solve this problem using :
protected function _initModules() {
// Call to prefent ZF from loading all modules
$this->bootstrap('frontController');
$front = $this->frontController;
$autoloader = Zend_Loader_Autoloader::getInstance();
$modules = $front->getControllerDirectory();
$default = $front->getDefaultModule();
foreach (array_keys($modules) as $module) {
if ($module === $default) {
continue;
}
$autoloader->pushAutoloader(new Zend_Application_Module_Autoloader(array(
'namespace' => ucwords($module),
'basePath' => $front->getModuleDirectory($module),
)));
}
}
In the application bootstrap.
Sorry for my bad english writting…
Thomas Dutrion
30 Jan 12 at 00:38
Thanks for the code addition. I’ll see if i can add that to the post soon. Your english is fine by the way.
Cheers,
Thijs
Thijs Lensselink
30 Jan 12 at 09:16