Module-specific models in Zend Framework

Posted

A post this week on PHP::Impact looks at the handling of modules in ZF, particularly the issue of module-specific models. Frederico's solution for this involves calling a particular function when you want to load a model. The way I solved this was a little different - I have a simple controller plugin that uses a dispatchLoopStartup method to grab the current module name from the request and add its model directory to the PHP include_path. That way, assuming you're using Zend_Loader, you can instantiate your module classes in the same way that you would any other.

Here's a quick example of how this works (code is untested). Assuming a directory structure based on the proposed standard one in the ZF wiki:

application/
   config/
   controllers/
   layouts/
   models/
   modules/
      news/
         controllers/
         models/
         views/
   views/
data/
library/
scripts/
tests/
www/

In my bootstrap I define two constants - ZF_PATH (full path to the Zend Framework library directory), and APP_PATH (full path to the current project). I then use these to set the PHP include path initially:

set_include_path(
        get_include_path() . PATH_SEPARATOR .
        ZF_PATH . PATH_SEPARATOR .
        APP_PATH.'/application/models'
);

then I have a front controller plugin which looks something like this:

class Myapp_Plugin extends Zend_Controller_Plugin_Abstract
{
        public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
        {
                set_include_path(
                        get_include_path() . PATH_SEPARATOR .
                        APP_PATH.'/application/modules/'.$request->getModuleName().'/models'
                );
        }
}

Register this plugin with your front controller and then as long as your module models follow the standard class naming conventions you don't have to do anything special to load them in.

The only disadvantage of this approach is the performance hit of an additional directory in the include path, but I'm hoping this will be negated by an optcache (something I have yet to benchmark).

Frederico's post has spawned a more general discussion on modules in ZF which I have some views on but that's a topic for another post.

Comments (3) Tags: zend framework, modules, models

Comments

Rhino
6th Feb, 2009

This works really nice man, thanks! So far profiling doesn't show any significant performance hit for adding the extra directory to include_path, but I only have a few models right now so that may change later.

Anyway, nice work.

grabur
24th Mar, 2009

This is fine unless you want to use a model from one module from another module?

Tim Fountain
25th Mar, 2009

Yup, you're quite right, I've not found a decent solution for that. In that situation I've just been using Zend_Loader::loadClass(), as you can pass it a path to search. So you just call that method and pass it the path to your module directory.

Another problem I've had more recently is that I've setup my modules so that each one has its own helper directory. But when you're calling a helper from another module in your layout, and it needs to load in its own models, you hit problems.

I'm hoping the resource loader stuff coming in 1.8 will solve all of these issues.

Add Comment

(Never shown on the site)

(Newlines preserved, format with Markdown)