Added by Gavin, last edited by Matthew Weier O'Phinney on Aug 12, 2008  (view change)

Labels

 
Deprecated

This page is deprecated in favor of the new project layout proposal.

Choosing Your Application's Directory Layout

This document demonstrates and named types of file organization schemes (layouts) that are commonly found in dynamic web applications. This document aids developers starting new projects by explaining the pros and cons associated with each of the popular layouts below. Community contributed suggestions and guidelines help provide insight into suggested approaches for organizing code into a hierarchical layout, while also giving developers a nomenclature to discuss their layouts with others.

For an in-depth look at the Conventional Modular Layout discussed below, please see the ZFDemo Tutorial.

Layouts

The following represent common layout variations you might find from application to application. They are presented in alphabetical, specialized order.

All references to directories named "/var", "/variable", "/tmp", or "/temporary" should be interpreted as implying the use of a unique prefix to avoid security issues. For example, "/tmp" should actually be interpreted as "/my/permission/protected/tmp", and not the shared "/tmp" found on many *nix systems. Likewise the other top-level directories, like "/application" are also meant to have deployment-specific prefixes (e.g. /home/me/myZFApp/application).

Classical (Unix/Linux-like)

Initially broken down into two main directories, web-readable and application files. This style mimics Unix/Linux OS directory layouts, and would be preferred by someone who favors Unix/Linux-style naming conventions.

/application
    /etc
    /lib
        /Zend
        /(other libraries)
    /usr
        /controllers
        /models
        /views
    /var
        /sessions
        /cache
        /view_compiles
/htdocs
    /images
    /scripts
    /styles

Pros

  • Self-contained; application-related files that are not publicly-accessible are in one place
  • Library files located locally (not server-wide)
  • Strong layout when models, views, and controllers have overlap, or are interrelated

Cons

  • Cryptic naming convention not common to people outside the Unix/Linux world
  • Grouping of all models, views, and controllers into a single location is seen as poor practice if they are not related. For example, think of a site's blog-related code and its poll-related code.

Classical Extended

/application
    /config
    /library
        /Zend
        /(other libraries)
    /user
        /controller
        /model
        /view
    /variable
        /sessions
        /cache
        /view_compiles
/htdocs
    /images
    /scripts
    /styles
    index.php

Pros

  • Same as Classical
  • Shorter Unix/Linux-style names lib, usr, and var are replaced with full length names for clarity

Cons

  • Same as Classical, except for the cryptic naming scheme

Classical Extended Embedded

In certain environments, moving the application-related files outside the web-readable directory might not be an option. In this case, the files are in the web readable directory and should be protected via an .htaccess file if at all possible, or some other related protection mechanism.

Security concern
Directly exposing application files to the outside world can potentially result in sensitive information about the application or server being revealed to attackers.
/htdocs
    /application
        /config
        /library
            /Zend
            /(other libraries)
        /user
            /controller
            /model
            /view
        /variable
            /sessions
            /cache
            /view_compiles
        .htaccess (deny from all)
    /images
    /scripts
    /styles
    index.php

Pros

  • Useful in environments where htdoc directory is all a developer has access to

Cons

  • This layout could present security issues if not properly configured
  • The route /application/ is not available for use due to it existing in the file system

Conventional

/application
    /config
    /controllers
    /models
    /views
/htdocs
    /images
    /scripts
    /styles
    index.php
/library
    /Zend
    /(other libraries)
/tmp
    /sessions
    /cache
    /view_compiles

Pros

  • With the exception of user created library code, application related code (as it relates to the domain model, controllers and views) is in one specific location.
  • Can take advantage of a library installed globally on a system (like PEAR)
  • As opposed to a Classical layout, focus on code containment is at the main directory level, thus creating a wider directory structure at the top most level.
    • Application directory in this layout means 'the code responsible for the direct duties of carrying out application specific actions'.
    • Library directory in this layout are librarys of code that carry out a specific and common pattern of duties, usually not related to the specifics of an application, but related to the carrying out of common tasks.
    • Tmp, or 'variable' directory, exists to aid the application in its duties that may require the use of a filesystem to create tmp files like session files, cache files or view compiles.
  • When an available option, this is the suggested format of the Zend Framework.
    • Using the most common or most encouraged format aids future developers (that might inherit or use your software) by reducing thier time getting up to speed.

Cons

  • Wider top level of directories. If your perception of application directory is not limited to the site specific files and includes libraries and system (tmp) files.
  • Harder to move top files into an Embedded structure (within the htdocs directory) as each concrete directory must be secured against web readability, and routes by the same name as concrete directories cannot exist (easily).
  • Certain applications might require custom (or extended) libraries, in that case, it is important to note that you not distinguish between 3rd Party libraries and user generated libraries. Library code is simply, regardless of source, library code.

Conventional Modular

In this style, models, views, and controllers for a specific application module are grouped into logical "packages", or directories.

/application
    /config (optional)
    /(module 1)
        /config (optional as needed)
        /controllers
        /models
        /views
    /(module 2)
        /controllers
        /models
        /views
    /(module n)
        /controllers
        /models
        /views
/htdocs
    /images
    /scripts
    /styles
    index.php
/library
    /Zend
    /(other libraries)
/tmp
    /sessions
    /cache
    /view_compiles

Pros

  • same as Conventional
  • Allows for packaging of non-interrelated application components (think plugin architecture of a web site with a blog, polls, quote generator).

Cons

  • same as Conventional

Naming conventions

Name Common alternatives
htdocs www, public_html, or inetpub
images img
scripts js or javascript
styles css

Don't forget 'document_root' as a htdocs alternative as suggested by Matthew in the Zend_Controller docs!

I am struggling to install on a System i5. I have read through lots of information and do have it working to a fashion but I dont think its ideal. Anyone who can add comments about the configuration would be appreciated.

I have a single ILE Apache Server running Virtual Hosting. This is using the PASE Apache server for all PHP page builds. I use ProxyReverse to acheive this. Anyone who wants to see my configs I can post.

I had to install the Rewrite directives in the PASE Apache server as I did the rewrite.log.
I then had a working solution where the index.php with standard html would work.
I then tried to link up with some dummy Framework calls to just show how its works. I had some problems with the Zend.php include as the php.ini file didnt seem to work as expected. there is a [ZEND] section which had an include entry to /usr/local/zend/core/pear. I found an entry which had a include entry commented out above this and changed to the actual path I have set to the Framework /usr/local/Framework-0.7.0/library, however server came back with an error saying it could not find the Zend.php file. I change the entry after the [ZEND] marker and it works fine?? but I then had to address a problem in the index.php file. I had the controller path set to Application/controllers which seemed to fit in with the structure, it could not find the controller page, I had to set it to /www/website/Application/controllers for it to work. This is all fine but I am trying to understand how this should be setup?

This may not be the right place to put these questions but I could not find a forum associated with the framework? I will post it on the ZendCore for i5/OS forum but it seems out of place there?

Chris..

Is there a way to separate css, img, js directories into the module directories. This would be ideal so I can easily reuse a module with styles and javascript without having to copy things here and there. This is how it works in cakephp, where you can just drop a 'plugin' into their plugin directory and it automatically works without setting up routes, and doing all this altering of various scripts to get things where they need to be.

why in some variations controller dir is named 'controllers', and in other just 'controller' (plural - singular) ?

If you are forced to put your configuration files in the web root, one other thing you can do is rename your config file with a .php extension and add a comment line at the top that contains "<?php"

Example file "config.ini.php":

;<?php
[section name]
var=value

This file can be used by the Zend_Config_Ini class, but will generate a parse error if anyone tries to access it via a URL. 

Hi there!

I think the conventional modular directory structure should look more like this:

  • All project related files are in a single directory - easy to maintain.
  • Modules are in an separeted folder (modules/) of the application directory - Its easier to maintain and it is clear what modules are installed/used.
  • The library/ directory in the application dir should be used only for overloading classes specific for this application.
  • The Zend Framework (and other librarys you are using) should be in the 'library/' dir outside the application dirSo it is easier to maintain applications.
  • The bootstrap.php file (name this file as you like) should be 'required' in the index.php in the htdocs directory. So the only line in index.php should be:

I hope the current modular directory structure gets an update with this suggestions in mind.

Best regards