In Defiance of Titles

Just another WordPress.com weblog

Distributing Zend Framework Modules

with 8 comments

It’s been almost a month now since the release of Zend Framework 1.8, and although I was very excited about some of the new features, it’s taken me awhile to digest that excitement into something bloggable. As a result, I apologize if I’m a bit late to the party…but I’d like to take a moment nonetheless to discuss the implications of my favorite 1.8 feature: Zend_Application_Resource_Modules.

Zend Framework has provided what it calls a “conventional modular directory structure” for quite some time now: specifically, Zend Framework modules are supposed to “[allow] you to separate different MVC applications into self-contained units, and re-use them with different front controllers”. Unfortunately, up until 1.8, I have never found this to be entirely accurate. Based on module architectures I’d seen in full-stack content management systems, I’d always kind of hoped that installing a module would be as easy as this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Hooray, it works now!

Now, this was true enough for modules that only provided a couple controllers and view scripts, but the second you introduced, say, controller plugins or models in the include_path, you’d have to modify your application-level bootstrap file, providing it with detailed knowledge of what the module provides. Because of this, the framework hasn’t really inspired a lot of distributable, reusable third-party modules; after all, the process for installing them would actually have looked something like this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Adjust your application entry point (index.php) to include the module’s models folder in the include_path.
  3. Adjust your application-level bootstrap file to register the new modules directory with the front controller, if you haven’t configured it that way already.
  4. Adjust your application-level bootstrap file to register any plugins or plugin paths it might provide.
  5. Install any database schemas that might have come with the module.
  6. Hooray, it works now!

The problem here is that the parent application (and the person installing it) has to know all sorts of nitty-gritty details about how the module does its business. In my opinion, a truly “self-contained” module would be able to handle a lot of the above process all by itself, without any modifications to the parent application; otherwise, it’s not really self-contained, and not particularly easy to distribute to other developers.

Enter 1.8

However, as I mentioned earlier, this situation has changed dramatically in Zend Framework 1.8, due to a wonderful little component called Zend_Application_Resource_Modules. Among other things, it provides the following:

  • Modules can now provide their own bootstrapping logic; no more need to register module-provided plugins, paths, etc. in the application-wide bootstrap file.
  • Autoloading of common types of module-provided classes is now automatically set up for you; no more need to add modules to your include_path, or even to require_once your module class files before you use them.

See the benefit? All of the application-level configuration we used to have to do can now be encapsulated in a bootstrap process provided as a part of the module itself. This cuts the above workflow down to something like this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Install any database schemas that might have come with the module.
  3. Hooray, it works now!

Suddenly, the prospect of downloading somebody else’s reusable module is a lot more appealing.

Some further issues

You’ll notice, however, that this still doesn’t quite match my first ideal workflow. Although Zend_Application_Resource_Modules provides a lot of assistance in getting your modules bootstrapped once they’re installed, it cannot yet provide much assistance with the installation process itself. As a result, if you’re trying to install a distributed module that involves database schemas, you’ll still have to install those by hand.

It’s also worth noting that Zend_Application_Resource_Modules does not yet provide a way to track and enforce module dependencies. For the most part this isn’t necessary; by the time everything is bootstrapped, all module-provided code is available through autoloading. However, there are a couple of situations in which it would be necessary:

  • If Module A needs to use a class provided by Module B during Module A’s own bootstrap, Module B must have been bootstrapped first…otherwise the autoloader for Module B’s classes won’t be ready yet.
  • If Module A provides a plugin that, for whatever reason, assumes that a plugin from Module B always fires before it, then Module B’s plugins need to be registered before Module A’s.

I’m working (in my copious spare time) on a distributable module of my own right now that could really benefit from both dependency tracking and database installation…but with how much better module architecture has already gotten in 1.8, I can only assume that future releases will be even more elegant. In the meantime, keep an eye out for my new module; I’d love the benefit of community review once it’s ready.

Advertisements

Written by jazzslider

May 21, 2009 at 7:43 pm

8 Responses

Subscribe to comments with RSS.

  1. […] Jensen has written up a new blog post about using modules in the Zend Framework and how to use them from multiple places in your […]

  2. dependency management is easy when you:
    – don’t allow circular dependencies.
    – constrain individual modules to explicitly declare their dependencies
    – use the above declarations to build a digraph where the modules are nodes and the edges are the actual dependency relations
    – sort said digraph topologically, which shall provide a correct loading order for the modules

    the hardest part is constraining the modules. if you don’t want to tell other developers to declare things just to make you and your bootstrapper/loader happy, you can always collect the dependency metadata (who needs who and when) and put it into your own little repository.
    i would recommend some notation that is compatible with the graphviz dot markup, so that way you can easily draw neat little graph diagrams too 🙂

    fqqdk

    May 27, 2009 at 4:54 pm

  3. damn, i should have read more carefully, who am i trying to.. erm.. bullshit?

    fqqdk

    May 27, 2009 at 5:00 pm

  4. @fqqdk no problem! Actually, if someone were to put together a centralized repository site for distributable ZF modules, it would be worth setting up a graphviz display of dependencies so that people knew what to download.

    That said, the thing I’m hoping for the most is that Zend_Application_Resource_Modules would eventually support dependency management in the same way that a Zend_Application bootstrap supports it for bootstrapping resources. That is, a bootstrap resource can declare its dependencies programmatically simply by asking the bootstrapper to bootstrap them:

    $bootstrap->bootstrap(‘otherresource’);

    I’d love to see the same thing happen in the modules resource:

    $modulesResource->bootstrap(‘othermodule’);

    That way the dependencies would manage themselves (though this creates other questions, which I may post about another time if they don’t come up in the comments here).

    jazzslider

    May 28, 2009 at 7:04 am

  5. […] Jensen has added another post (a followup to a previous one looking at Zend Framework modules) about a “first draft” of a practical application of […]

  6. Did you tried to set up a modular application with Zend_Framework? For me this is a big fail for ZF team.

    Nicolae

    June 28, 2009 at 12:54 pm

  7. @Nicolae,

    I’ve been working on some standalone modules that can be used in Zend Framework applications, but the whole project is a long ways off. However, I haven’t found that it’s the framework standing in my way…rather, I just don’t have enough free time to devote to the project. The new module bootstrapping and autoloader functionality in Zend Framework 1.8 has really done a lot to make it easier to write standalone, redistributable modules; if you haven’t done any work with 1.8 yet, I’d highly recommend it. Prior to this version, modules were more difficult, I’ll admit…but they’re definitely getting better.

    jazzslider

    June 28, 2009 at 5:07 pm

  8. So I take it (from what you said above) that there is currently no user-contributed modules’ repository? That’s a shame.

    Sam

    July 19, 2009 at 3:41 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: