Where to place module specific classes in the Zend Framework

Wednesday, December 16, 2009

I truly believed that creating self contained units and re-using them would be possible with Zend Framework Modules. But I couldn’t figure some things out; like where to put module specific classes.

After reading the reference guide this became clear, but only after reading it trough and trough and after finding this section on resource types that are set by default in the Zend_Application_Module_Autoloader class.

In this section there are a couple of default resource types explained -or actually the ones that are set by default. Of course the actual defaults are different. Just try the following code in a module bootstrap resource method like this:

protected function _initAutoload()
{
    // constructor requires both a namespace and a path
    $autoloader = new Zend_Application_Module_Autoloader(array(
        'namespace' => 'Test_',
        'basePath'  => dirname(__FILE__),
    ));
        
    // show the default resource types / mappings
    print_r($autoloader->getResourceTypes());die;
}

With running this code you will see the following output (below), the default resource types set for your module. What we can learn here is how all the resources mapped within your module and why we can use lowercase directory names and why we have plural names like models, forms etc.

Array
(
    [dbtable] => Array
        (
            [namespace] => Test_Model_DbTable
            [path] => APPLICATION_PATH \modules\test/models/DbTable
        )

    [form] => Array
        (
            [namespace] => Test_Form
            [path] => APPLICATION_PATH \modules\test/forms
        )

    [model] => Array
        (
            [namespace] => Test_Model
            [path] => APPLICATION_PATH \modules\test/models
        )

    [plugin] => Array
        (
            [namespace] => Test_Plugin
            [path] => APPLICATION_PATH \modules\test/plugins
        )

    [service] => Array
        (
            [namespace] => Test_Service
            [path] => APPLICATION_PATH \modules\test/services
        )

    [viewhelper] => Array
        (
            [namespace] => Test_View_Helper
            [path] => APPLICATION_PATH \modules\test/views/helpers
        )

    [viewfilter] => Array
        (
            [namespace] => Test_View_Filter
            [path] => APPLICATION_PATH \modules\test/views/filters
        )
)

What we can also see is that this list of defaults set is larger than stated in the reference guide. But oh well. I have replaced parts of the actual paths with APPLICATION_PATH to make this a little more readable.

So now we understand how resources are set we can just add out own, and place our module specific classes there. I decided to go with the missing default resource Api as I think that name suits the purpose. Namely the module Application Programming Interface.

My module bootstrap resource method for the most part looks like this:

protected function _initAutoload()
{
    // constructor requires both a namespace and a path
    $autoloader = new Zend_Application_Module_Autoloader(array(
        'namespace' => 'Test_',
        'basePath'  => dirname(__FILE__),
    ));
        
    // Add resource type for Module Api
    $autoloader->addResourceType('api','api','Api');
}

With this I have set up my module to to have a place in which I can now put my module specific classes. The folder test/api then becomes my 'library' for all the module's specific classes. And all Api Classes will then have a prefix of Test_Api_ and with this resource mapped you can create sub folders using the standard naming convention as desired.

On top of this, as module bootstrap classes are instantiated on every request by Zend_Application you have access to these module specific classes anywhere in your application. So with 'plugging' your module in a Zend Framework application it becomes accessible to your application, and in this example its Api. As far a dependencies go - I think - this is how modules can be used in applications. They themselves do not know in what context they operate (in which of your Zend Framework Application it is used). Should you wish to use part of your modules' Api (or other functionality) elsewhere go ahead, as you know the module is present in your application use it at will. This makes the dependencies only exsist downward. Meaning, your application will then become dependent on the module and not the other way around.

One more thing about dependencies between modules; I think you should avoid these. Which then raises the question what is a module?.

To me a module is something that can be re-used, is self contained and is in part a domain itself. I have read an interesting blog post about the Domain Model, here it explains what we are actually modeling and I think that goes for our modules to.

Comments

Chris F says:
Thursday, July 14, 2011
You could also add it to the Zend_Application_Module_Autoloader instance already setup by Zend_Application: protected function _initAutoload(){ $this-getResourceLoader()-addResourceType('api','api','Api'); }

Leave a reply

 
Please type this word backwards: bib4h
 
 
 

Blog categories

Zend-Framework Databases Php

About

Sreknord.net is the personal web space of software engineer, Leonard Dronkers (NL). At Sreknord.net you will find interesting information about software engineering and web-development.

Leonard Dronkers

Software engineer, Leonard Dronkers is currently working as a web-developer at VNU Media (NL).

Professional interests:

To get in touch with Leonard, please use the contact form.