Zend Framework 2 modules with subnamespaces

Zend framework 2 has a new module approach that lets you set things up almost any way you would like. When I create code for myself, I always use the same root namespace ‘Ctrl’. and I want to keep it that way.
For a small testproject I currently have 3 modules of my own:

  • The first one is the application module which will house the MVC application and its classes, its root namespace is ‘AppName’ and it resides in the ./module/AppName directory
  • The second one is a class library module, its root namespace is ‘Ctrl’ and it resides in the ./vendor/ctrl-f5/ctrllib directory
  • The third one is an Auth module, which also contains its own mvc application and classes, the root namespace is ‘Ctrl\Modules\Auth’ and it resides in the ./vendor/ctrl-f5/auth directory

ZF2 allows modules to have any namespace you want, as long as you configure the autoloader correctly, when using subnamespaces you should specify the correct path in the module listener config. This means it should go look for classes in the ‘Ctrl\Modules\Auth’ namespace in the Auth module first, before falling back to the ‘Ctrl’ module.

Here are the application config and the module class with the relevant parts:

<?php
// ./config/application.config.php

return array(
    'modules' => array(
        'Ctrl\Module\Auth',
        'Ctrl',
        'AppName',
    ),
    'module_listener_options' => array(
        'config_glob_paths'    => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
            'Ctrl\Module\Auth' => './vendor/ctrl-f5/auth/',
            'Ctrl' => './vendor/ctrl-f5/ctrllib/',
        ),
    ),
);
<?php 
// ./vendor/ctrl-f5/auth/Module.php

namesapce Ctrl\Module\Auth;

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/Auth/',
                ),
            ),
        );
    }
}

easymode

to see how I fixed the ViewManager to resolve the default template names, check out my next post