Nested (sub-folder) controllers in Zend Framework v1.x
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Nested controllers in Zend Framework v1.x

This project provides an application resource plug-in for Zend Framework v1 to automate the construction of the routes necessary to be able to nest controllers within modules. An example Zend_Application-based project is also provided to demonstrate how to use the resource plug-in.

The resource leverages Matthew Weier O'Phinney's work to backport the classmap-based autoloader from Zend Framework 2 for use in ZFv1 projects. More specifically, it uses the classmaps generated by the command-line tool to enumerate all the controllers in each module and map routes to them accordingly.

The necessary code is linked in from Matthew's github repository via a git submodule stored in external/zf1-autoloaders.


Show these guys some love:

  • Matthew Weier O'Phinney (weierophinney) for his work on the ZF2 classmap autoloader
  • Ryan Mauger (bittarman) for showing me that ZFv1 could do nested controllers, and sharing an example:


Controller Setup

To create nested controllers, simply create sub-folders within the controllers directory of the module you wish to add the controller(s) to. The included example application has the following structure inside the application/modules directory:

  • default
    • controllers
      • SectionOne
        • PageOneController.php (Default_SectionOne_PageOneController)
      • IndexController.php (Default_IndexController)
      • ErrorController.php (Default_ErrorController)
  • admin
    • controllers
      • Page
        • SubPage
          • DisplayController.php (Admin_Page_SubPage_DisplayController)
        • DisplayController.php (Admin_Page_DisplayController)
      • StandardController.php (Admin_StandardController)

When you add new nested controllers to a module in your project, you will need to rebuild the classmap file for that module (or the entire project depending on how the plugin is configured):

cd bin;

# if using per-module classmaps, run:
php module_classmap_generator.php --module <module name>

# if using single application-wide classmap, run:
php application_classmap_generator.php

To run this tool, please be sure to have a recent Zend Framework installation on your path

Bootstrap Setup

To enable the application bootstrap resource which configures the routes for our nested controllers you must add the following lines to your application.ini:

;; These configurations enable nested controller support
autoloaderNamespaces[] = "CDLI_Standard_"
pluginPaths.CDLI_Standard_Mvc_Resource = "CDLI/Standard/Mvc/Resource"
resources.subcontrollers[] =

And you're done! Your application should now be able to route directly to nested controllers.

Classmap Files

By default, the resource plugin is configured to operate using one classmap file per module. To change this, add the following line to your application.ini file:

resources.subcontrollers.singleClassmapFile = true

And then run the application_classmap_generator.php script referenced above. This will build a single classmap file named application/.classmap.php, and all routes will be built from this file.

If you would prefer to use a classmap filename other than .classmap.php, follow these two easy steps:

  1. Rename your existing classmap files, or generate new ones. Both classmap generator scripts accept the --classmap-file argument which specifies the output filename. For example, to use autoload_classmap.php instead:

     # if using per-module classmaps, run:
     php bin/module_classmap_generator.php --module <module name> --classmap-file autoload_classmap.php
     # if using single application-wide classmap, run:
     php bin/application_classmap_generator.php --classmap-file autoload_classmap.php
  2. Add the following line to your application.ini file:

     resources.subcontrollers.classmapFilename = <classmap filename>

    Where <classmap filename> is the name you chose in #1 above.


Given a nested controller setup such as the following:

  • admin
    • controllers
      • Page
        • SubPage
          • DisplayController.php (Admin_Page_SubPage_DisplayController)
        • DisplayController.php (Admin_Page_DisplayController)
      • StandardController.php (Admin_StandardController)

and the associated classmap file (paths clipped for brevity):

$dirname_4ddfa1d65bbdc = dirname(__FILE__);
return array (
  'Admin_StandardController' => ...,
  'Admin_Page_SubPage_DisplayController' => ...,
  'Admin_Page_DisplayController' => ...,

The application bootstrap resource CDLI_Standard_Mvc_Resource_Subcontrollers will construct a custom route for each of the nested controllers:

admin/page/sub-page/display/:action -> Admin_Page_SubPage_DisplayController
admin/page/display/:action -> Admin_Page_DisplayController

Non-nested controllers such as Admin_StandardController are not processed, as these are routed properly by the default route.


This code is considered proof-of-concept, and has not been vetted or tested for inclusion in a production environment. Use of this code in such environments is at your own risk.

Released under the New BSD license: