views:

3648

answers:

6

I'm relatively new to MVC and the Zend Framework. That being said, I feel like I have a hard time figuring out where Forms belong in my directory structure. I have a modular directory structure, so I don't know if there should be a single forms directory, or one within each module directory.

/application
    /modules/
        /default
            /controllers
            /views
        /admin
            /controllers
            /views

Once you've decided a directory for forms, do you set that directory in the include path of the bootstrap? Or do you include the form in the controller that it's being used in?

How do you use forms with the Zend Framework?

A: 

As of March '09 the ZF thought leaders still seem to be debating the best ways to organize everything. There is a scaffolding-generator as a part of Zend_Tool slated for release in ZF v1.8. It's currently in the incubator, I tried it last week and it works, but there are not many components generated in its current state.

From the examples I've seen it seems that they are best managed separate from the models they interact with (this is from Zend Framework In Action):

/application
    /modules/
        /default
            /controllers
            /forms
                ContactForm.php
                LoginForm.php
                RegisterForm.php
                SupportForm.php
            /models
                Comment.php
                User.php
                Users.php
            /views
        /admin
            /controllers
            /views

However, I've also seen structured with the forms below the model directory. Matthew Weier O'Phinney shows how to use them for validation on models themselves:

/application
    /modules/
        /default
            /controllers
            /models
                Comment.php
                User.php
                /Form
                    Comment.php
                    Login.php
                    Register.php
            /views
        /admin
            /controllers
            /views

To have your files automatically included be sure to name your classes using the underscore model.

For example, when Zend_Loader sees

 class RegisterController extends Zend_Controller_Action

It looks in the php include_path for:

Zend/Controller/Action.php

Similarly, assuming the first structure above, if we include the 'default' module in our include_path:

# bootstrap.php
$rootDir = dirname(dirname(__FILE__));
define('ROOT_DIR', $rootDir);
set_include_path(get_include_path()
    . PATH_SEPARATOR . ROOT_DIR . '/library/'
    . PATH_SEPARATOR . ROOT_DIR . '/application/modules/default/'
);
include 'Zend/Loader.php';
Zend_Loader::registerAutoload();

You name your classes:

Forms_ContactForm
Models_User

Some programmers choose to put most of their files in the library so they don't have to add extra include paths:

/library
    /My
        /Form
            Contact.php

Assuming the library folder is included, the class above would be named:

My_Form_Contact

Best of luck! -Matt

Matt Gardner
I've added some additional notes in the reply above. Let me know if you have questions.
Matt Gardner
Problem with this method is that you have to add every module directory to the include_path. And also Forms_ContactForm seems redundant and ugly.
leek
I agree completely, that particular folder structure was used with include statements (not intended for Zend Loader). And in any case, your suggestion is indeed far more elegant. :)
Matt Gardner
+1  A: 

Personally, I found it easiest to put my module directory in the include path and name my form classes in the Zend Loader pattern.

Example directory structure (copying from Matt's answer):

/application
    /modules/
        /default
            /controllers
            /forms
                Contact.php
                Login.php
                Register.php
                Support.php
            /models
                Comment.php
                User.php
                Users.php
            /views
        /admin
            /controllers
            /views

Example form class names:

Default_Forms_Contact
Default_Forms_Login
Default_Forms_Register
Default_Forms_Support

I name my models and plugins similarly to keep things simple.

I hope this issue is addressed correctly in later versions of the Zend Framework.

UPDATE: This structure doesn't work on *nix platforms. Found that out the hard way! The Zend Loader needs the module, forms, and models folders to be capitalized to work in a case sensitive environment.

leek
Just to note: I also think '{Module}_Forms_{Name}' is ugly too.
leek
A: 

I put all my models in a folder in the library. Notion is my company's name.

/application
/modules/
    /default
        /controllers
        /views
    /admin
        /controllers
        /views
/libray/
    /Zend
    /Notion
        /Form

This makes it easy to include and find files as you already have the library folder included.

Notion_Form_Login
Notion_Db_Manager_Login
Biff
what if you have different forms for different modules?
rvdavid
+1  A: 

i personally like to keep them in my application folder, since i dont think they belong in the library and having just one folder makes autoloading them easier.

/application
/forms
/modules/
    /default
        /controllers
        /views
    /admin
        /controllers
        /views
/libray/
    /Zend

and i just added the form path to the includes_path and i am good to go.

solomongaby
+4  A: 

It's a little late but in the current version of ZF this has been solved:

On the following page http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html The manual states:

30.3.2. The Module Resource Autoloader Zend Framework ships with a concrete implementation of Zend_Loader_Autoloader_Resource that contains resource type mappings that cover the default recommended directory structure for Zend Framework MVC applications. This loader, Zend_Application_Module_Autoloader, comes with the following mappings:

api/         => Api
forms/       => Form
models/      => Model
    DbTable/ => Model_DbTable
plugins/     => Plugin

As an example, if you have a module with the prefix of "Blog_", and attempted to instantiate the class "Blog_Form_Entry", it would look in the resource directory's "forms/" subdirectory for a file named "Entry.php". When using module bootstraps with Zend_Application, an instance of Zend_Application_Module_Autoloader will be created by default for each discrete module, allowing you to autoload module resources.

This does, however, require the use of Zend_Application

Nicky De Maeyer
Good to know! I haven't kept up with the recent changes so it helps to know this has been addressed in current versions.
Andrew
just what I was looking for. I went the model/forms route and currently refactoring my structure to align with zend standards/recommendations.
rvdavid
A: 

the zend command tool can create forms for that:

zf create form product sales

where sales is the name of the module, the command tool create a directory form inside module sales and a file Product.php with a class:

class sales_Form_Product extends Zend_Form {

and you have to add a definition of de Zend_Application_Module_Autoloader, to define your module's directory

armandfp