Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct or preferred directory structure for a Zend Framework 2 module?

I would like to get to grips with Zend Framework 2 by using it for a small project. I have been through various blogs articles, docs and of course the fantastic tutorial by Akrabat (Rob Allen).

However, in all my reading I have not come across any explanation on the correct or preferred directory structure for a module that Zend Framework 2 expects.

In the Akrabat tutorial Rob Allen's example module makes use of a single model and controller. The directory structure he chose was:

/module
    /Album
        /config
        /src
            /Album
                /Controller
                /Form
                /Model
        /view
            /album
                /album

This is all fine, but what if a module had multiple controllers and models as you would expect in a site that had multiple pages/sections? Would I put all my controllers in the /src/Album/Controller directory, or would I create another set of /src/xxx/ directories for each additional model and related controllers and views?

In the /view directories, do I break it up into sub-directories for each set of views used by the various controllers?

I think the confusion for me comes from the fact that in Rob's example, his main Controller/Model is the same name as the module. So his Album module has a directory, with more Album directories for the models, controllers and views. If I were to rename his module from Album to, say, MyModule would the directory structure then become:

/module
    /MyModule
        /config
        /src
            /Album
                /Controller
                /Form
                /Model
        /view
            /MyModule
                /album

Would it then follow that an additional model, Artist, and associated controllers would be organised thusly:

/module
    /MyModule
        /config
        /src
            /Album
                /Controller
                /Form
                /Model
            /Artist
                /Controller
                /Form
                /Model
        /view
            /MyModule
                /album
                /artist

If not the above, then what structure would it be?

This is of course all assuming ZF2 expects a strict structure. If this is not the case then obviously I can organise it pretty much the way I want.

like image 873
Etzeitet Avatar asked Aug 08 '12 11:08

Etzeitet


1 Answers

To quickly answer your final question - ZF2 indeed doesn't care about the directory structure. Or I should rather say - it doesn't have a predefined structure. That is the reason it has the autoloader configurations and class maps (depending on which approach you choose to use).

The 'default' autoloader (see Module.php), which you can find in most of the examples only assumes that your ModuleName classes will be found in the ./src/ModuleName directory:

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

I assume you know that that's what those __NAMESPACE__ parts mean.

So, if you have a module called Cat, the classes of it would be expected to be found in ./modules/Cat/src/Cat.

If you would then decide to add some new functionality into your application, you would add another module called Dog and place its class files in ./Dog/src/Dog.

However, that in no way means you have to do it this way. You could also place all your animal related classes in one module called e.g. Animals. You would have to modify your autoloader to look like this:

// ./modules/Animals/Module.php
public function getAutoloaderConfig()
{
    return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                'Cat' => __DIR__ . '/src/Cat',
                'Dog' => __DIR__ . '/src/Dog',
            ),
        ),
    );
}

...and place your classes in files like ./modules/Animal/src/Cat/Persian.php and ./modules/Animal/src/Dog/Collie.php.

One thing I would suggest though is to think about modules as separate entities not knowing anything specific about the other modules. As a 'real-life' example - I have an application which has a frontend (html, css, etc.) and an API functionality.

I have 3 modules:

  • Application - contains database configs, db table classes, mappers, models, authentication classes, etc. Basically everything that any other module might need.
  • Api - has controllers expecting requests in a specific format and outputting it as e.g. JSON (i.e. no views required). Classes in this module are using classes from the Application module as I still need all the database functionality but having it all separate gives me the separation of the application-wide logic from the API logic. I could rip this module out I wanted to and it wouldn't break anything else.
  • Website - module responsible only for rendering pages. Yet again, it uses classes from the Application as I want to be able to render data from the database and let users edit it but I don't want the functionality solely in this module as Api needs it too.

My ./config/application.config.php loads them in this order:

return array(
    'modules' => array(
        'Application',
        'Api',
        'Website',
    ),
    // all other entries
);

This means that I have access to the Application classes from all other modules. If I wanted to disable my API for some reason, I would just remove the Api directory and my front end would still work.

Hope this helps! :)

TL;DR You can structure files any way you want, just don't forget to configure the autoloader correctly.

like image 149
Andris Avatar answered Oct 04 '22 15:10

Andris