View Source

<ac:macro ac:name="note"><ac:parameter ac:name="title">Deprecated</ac:parameter><ac:rich-text-body>
<p>This page is deprecated in favor of the <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend+Framework+Default+Project+Structure+-+Wil+Sinclair">new project layout proposal</a>.</p></ac:rich-text-body></ac:macro>

<h1>Choosing Your Application's Directory Layout</h1>

<p>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.</p>

<p>For an in-depth look at the Conventional Modular Layout discussed below, please see the <ac:link><ri:page ri:content-title="3. Application Topography and Configuration" ri:space-key="ARCHIVE" /><ac:link-body>ZFDemo Tutorial</ac:link-body></ac:link>.</p>

<h2>Layouts</h2>

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

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

<ac:macro ac:name="toc"><ac:parameter ac:name="minLevel">3</ac:parameter><ac:parameter ac:name="maxLevel">3</ac:parameter><ac:parameter ac:name="outline">true</ac:parameter><ac:parameter ac:name="style">none</ac:parameter><ac:parameter ac:name="indent">20px</ac:parameter></ac:macro>


<h3>Classical (Unix/Linux-like)</h3>

<p>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. </p>

<ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
/application
/etc
/lib
/Zend
/(other libraries)
/usr
/controllers
/models
/views
/var
/sessions
/cache
/view_compiles
/htdocs
/images
/scripts
/styles
]]></ac:plain-text-body></ac:macro>

<p><strong>Pros</strong></p>

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


<p><strong>Cons</strong></p>

<ul>
<li>Cryptic naming convention not common to people outside the Unix/Linux world</li>
<li>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.</li>
</ul>


<h3>Classical Extended</h3>

<ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
/application
/config
/library
/Zend
/(other libraries)
/user
/controller
/model
/view
/variable
/sessions
/cache
/view_compiles
/htdocs
/images
/scripts
/styles
index.php
]]></ac:plain-text-body></ac:macro>

<p><strong>Pros</strong></p>

<ul>
<li>Same as Classical</li>
<li>Shorter Unix/Linux-style names <code>lib</code>, <code>usr</code>, and <code>var</code> are replaced with full length names for clarity</li>
</ul>


<p><strong>Cons</strong></p>

<ul>
<li>Same as Classical, except for the cryptic naming scheme</li>
</ul>


<h3>Classical Extended Embedded</h3>

<p>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.</p>

<ac:macro ac:name="warning"><ac:parameter ac:name="title">Security concern</ac:parameter><ac:rich-text-body><p>Directly exposing application files to the outside world can potentially result in sensitive information about the application or server being revealed to attackers.</p></ac:rich-text-body></ac:macro>

<ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
/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
]]></ac:plain-text-body></ac:macro>

<p><strong>Pros</strong></p>
<ul>
<li>Useful in environments where htdoc directory is all a developer has access to</li>
</ul>


<p><strong>Cons</strong></p>

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


<h3>Conventional</h3>

<ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
/application
/config
/controllers
/models
/views
/htdocs
/images
/scripts
/styles
index.php
/library
/Zend
/(other libraries)
/tmp
/sessions
/cache
/view_compiles
]]></ac:plain-text-body></ac:macro>

<p><strong>Pros</strong></p>

<ul>
<li>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.</li>
<li>Can take advantage of a library installed globally on a system (like PEAR)</li>
<li>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.
<ul>
<li>Application directory in this layout means 'the code responsible for the direct duties of carrying out application specific actions'.</li>
<li>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.</li>
<li>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.</li>
</ul>
</li>
<li>When an available option, this is the suggested format of the Zend Framework.
<ul>
<li>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.</li>
</ul>
</li>
</ul>


<p><strong>Cons</strong></p>
<ul>
<li>Wider top level of directories. If your perception of <em>application directory</em> is not limited to the site specific files and includes libraries and system (tmp) files.</li>
<li>Harder to move top files into an <strong>Embedded</strong> 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).</li>
<li>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.</li>
</ul>



<h3>Conventional Modular</h3>

<p>In this style, models, views, and controllers for a specific application module are grouped into logical &quot;packages&quot;, or directories.</p>

<ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
/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
]]></ac:plain-text-body></ac:macro>

<p><strong>Pros</strong></p>
<ul>
<li>same as Conventional</li>
<li>Allows for packaging of non-interrelated application components (think plugin architecture of a web site with a blog, polls, quote generator).</li>
</ul>


<p><strong>Cons</strong></p>
<ul>
<li>same as Conventional</li>
</ul>


<h2>Naming conventions</h2>

<table><tbody>
<tr>
<th><p> Name </p></th>
<th><p> Common alternatives </p></th>
</tr>
<tr>
<td><p> <code>htdocs</code> </p></td>
<td><p> <code>www</code>, <code>public_html</code>, or <code>inetpub</code> </p></td>
</tr>
<tr>
<td><p> <code>images</code> </p></td>
<td><p> <code>img</code> </p></td>
</tr>
<tr>
<td><p> <code>scripts</code> </p></td>
<td><p> <code>js</code> or <code>javascript</code> </p></td>
</tr>
<tr>
<td><p> <code>styles</code> </p></td>
<td><p> <code>css</code> </p></td>
</tr>
</tbody></table>