<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://mirmodynamics.com/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Mirmo Dynamics - Tag - models</title>
  <link>http://mirmodynamics.com/</link>
  <atom:link href="http://mirmodynamics.com/feed/tag/models/rss2" rel="self" type="application/rss+xml"/>
  <description>Rien de grand ne se fit jamais sans enthousiasme.</description>
  <language>en</language>
  <pubDate>Wed, 03 Dec 2008 17:01:33 +0100</pubDate>
  <copyright>2003-2008 &amp;copy; Geoffrey Bachelet</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>How I use the Zend Framework</title>
    <link>http://mirmodynamics.com/post/2007/10/16/How-I-use-the-Zend-Framework</link>
    <guid isPermaLink="false">urn:md5:15540fb9e20bbf5beef4ab8f8c6150ed</guid>
    <pubDate>Mon, 22 Oct 2007 13:39:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>application</category><category>architecture</category><category>conventions</category><category>models</category><category>modules</category><category>php</category><category>zend framework</category>    
    <description>&lt;p&gt;Having started a few applications using the Zend Framework, I came out with a few practices that I tend to use over and over. In this post I'll quickly expose some of them and explain why I do things the way I do them. As you'll notice, most of them are already widely known and used over the &lt;acronym&gt;ZF&lt;/acronym&gt; developer's community. Please remember that these practices are just &lt;em&gt;what I do&lt;/em&gt;, and come with no garanty at all to be &lt;em&gt;best practices&lt;/em&gt;.&lt;/p&gt;    &lt;h3&gt;Directory structure&lt;/h3&gt;


&lt;p&gt;First thing to work out when starting a new Zend Framework powered application, at least if you decide to use the &lt;acronym title=&quot;Zend Framework&quot;&gt;ZF&lt;/acronym&gt;'s &lt;acronym title=&quot;Model View Controller&quot;&gt;MVC&lt;/acronym&gt; component, is the application's directory structure. Here is the one I used, which is a slightly modified version of &lt;a href=&quot;http://framework.zend.com/manual/en/zend.controller.modular.html&quot;&gt;the official recommended structure&lt;/a&gt;. This is essentially a standard modular structure with all directories needed to store various additional data from your application.&lt;/p&gt;

&lt;pre&gt;
application/
	cache/
	config/
		application.ini
		routes.ini
	data/
	layouts/scripts/
	library/App/
	logs/
	modules/
		default/
		user/
document_root/
	css/
	images/
	index.php
	js/
&lt;/pre&gt;


&lt;p&gt;As you can see, I have many directories, each dedicated to a specific file type. This has many advantages, such as always knowing where to find what you're looking for or easily process files of a certain type (think &lt;code&gt;grep foo logs/*&lt;/code&gt;). Also, I name my directories explicitly. I used to call the &lt;code&gt;config&lt;/code&gt; directory &lt;code&gt;etc&lt;/code&gt;, which is the directory holding most configurations files under UNIX systems, but it may not appear that clear to non-UNIX user, while &lt;code&gt;config&lt;/code&gt; is clear enough for everyone.&lt;/p&gt;


&lt;p&gt;Another point you might notice is the that all applications files and data are placed outside the document_root. This is done to avoid unwanted access to such resources. While this is the best way, in my opinion, to do, it may not always be possible (like when you have no control on your actual &lt;code&gt;DocumentRoot&lt;/code&gt;. In this case, you may consider having the following structure:&lt;/p&gt;

&lt;pre&gt;
application/
	cache/
	config/
		application.ini
		routes.ini
	data/
	layouts/scripts/
	library/App/
	logs/
	modules/
		default/
		user/
	tasks/
css/
images/
index.php
js/
&lt;/pre&gt;


&lt;p&gt;Then you can deny any web access to the &lt;code&gt;application/&lt;/code&gt; directory with the following &lt;code&gt;htaccess&lt;/code&gt; rules:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;Directory application&amp;gt;
    Order allow,deny
    Deny from all
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;


&lt;h3&gt;Did you say modular ?&lt;/h3&gt;


&lt;p&gt;Yeah, I said it actually. Modules in Zend Framework are groups of controllers (along with their corresponding views and models) which sits in their own namespace. One could argue that module's primary goal is to ease code re-use, but I personnaly dunno, as I personnally still have not seen such a use of modules. The drawbacks of re-usable code is that it needs to be abstract enough to fit ant particular situation or so. In this context, I only have a single separate module alongside the default one: the user module. It has Index and Auth controllers, respectively used to perform &lt;acronym title=&quot;Create Read Update Delete&quot;&gt;CRUD&lt;/acronym&gt; and login/logout operations.&lt;/p&gt;


&lt;p&gt;Having re-usable modules implies that all modules containes its own models, or at least, knows where (ie, in which other module) to find its required models. There comes Xend's model loader. This is an action helper which ease the load of models inside controllers, like:&lt;/p&gt;

&lt;pre&gt;
$this-&amp;gt;_helper-&amp;gt;modelLoader(array('MyCoolModel', 'MyOtherModel'));
&lt;/pre&gt;


&lt;p&gt;Easy heh ? The bad point with this helper is that it is restricted to, or at best tricky to use outside, action controllers. That is why I developped my own library loader which I shall present in another blogpost soon.&lt;/p&gt;


&lt;h3&gt;Models naming convention&lt;/h3&gt;


&lt;p&gt;Using the &lt;a href=&quot;http://svn.ralphschindler.com/repo/Xend/&quot;&gt;Xend&lt;/a&gt;'s model loader trained me to adopt what I consider a good model naming convention, basically, it just follows the controller's conventions, that is, prefix the model name with the module's name, so that for example my user model is named like &lt;code&gt;User_Users&lt;/code&gt; (the first &lt;code&gt;User&lt;/code&gt; is the module name, the second &lt;code&gt;Users&lt;/code&gt; is the &lt;code&gt;ucfirst&lt;/code&gt;'ed tablename). whenever I need to have row specific model I just postfix the whole model name with &lt;code&gt;_Row&lt;/code&gt;. It gives the following directory architecture:&lt;/p&gt;

&lt;pre&gt;
modules/user/models/
	Users/Row.php
	Users.php
&lt;/pre&gt;


&lt;p&gt;I'll eventually load &lt;code&gt;User_Users_Row&lt;/code&gt; from &lt;code&gt;User/Users.php&lt;/code&gt; with a simple require:&lt;/p&gt;

&lt;code class=&quot;php&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;require_once&lt;/span&gt; &lt;a href=&quot;http://www.php.net/dirname&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;dirname&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;__FILE__&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #ff0000;&quot;&gt;'/Users/Row.php'&lt;/span&gt;;&lt;/code&gt;


&lt;h3&gt;Personal library namespace&lt;/h3&gt;


&lt;p&gt;A recurring question from &lt;acronym&gt;ZF&lt;/acronym&gt; beginners is to know where they should put their own library classes. The answer is pretty simple actually. You just create your own library namespace alongside Zend's. Let's say you wish to extend &lt;code&gt;Zend_Db_Table_Abstract&lt;/code&gt; to add your own logic. The first thing to do is to choose the name of your namespace, we will use Foobar as an example, because this is a cool name. Your class will be named like &lt;code&gt;Foobar_Db_Table_Abstract&lt;/code&gt;, and located in &lt;code&gt;Foobar/Db/Table/Abstract.php&lt;/code&gt;, which in turn should be located anywhere in your &lt;code&gt;include_path&lt;/code&gt;. So you could have the following directory structure:&lt;/p&gt;

&lt;pre&gt;
application/library/
	Zend/
	Foobar/
	Riskle/
&lt;/pre&gt;


&lt;p&gt;Just remember &lt;acronym&gt;ZF&lt;/acronym&gt;'s naming convention: from the filename, strip the &lt;code&gt;.php&lt;/code&gt;, replace slashes (/) with underscores (_), and you've got the class name. Simple heh ?&lt;/p&gt;


&lt;h3&gt;App_ library namespace (App_Controller_Action, etc)&lt;/h3&gt;


&lt;p&gt;Additionnaly to my personal library namespace, I also have a special &lt;code&gt;App&lt;/code&gt; namespace, which I always locate into &lt;code&gt;application/library/App&lt;/code&gt;. This namespace principally provides two classes, &lt;code&gt;App_Controller_Action&lt;/code&gt; and &lt;code&gt;App_Db_Table_Abstract&lt;/code&gt;, which basically extend respectively &lt;code&gt;Zend_Controller_Action&lt;/code&gt; and &lt;code&gt;Zend_Db_Table_Abstract&lt;/code&gt;. All my controllers and models then use the &lt;code&gt;App_&lt;/code&gt; namespace as a reference, so that I can easily change the base class for all my controllers / models as easily as changing the parent of the corresponding &lt;code&gt;App&lt;/code&gt; class.&lt;/p&gt;


&lt;h3&gt;Using third party components&lt;/h3&gt;


&lt;p&gt;Using &lt;acronym&gt;ZF&lt;/acronym&gt; compatible components is just easy as dropping them in your include path. By &lt;acronym&gt;ZF&lt;/acronym&gt; compatible, I mean following the &lt;acronym&gt;ZF&lt;/acronym&gt; class naming convention. Just make source it's in your &lt;code&gt;include_path&lt;/code&gt;, and you can start using them right away. Components library I use includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://svn.ralphschindler.com/repo/Xend/&quot;&gt;Xend&lt;/a&gt;'s layout component&lt;/li&gt;
&lt;li&gt;Some components from &lt;a href=&quot;http://tools.assembla.com/svn/naneau_zf/library/Naneau/&quot;&gt;Naneau's library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My own library, &lt;a href=&quot;http://tools.assembla.com/svn/riskle/library/Riskle/&quot;&gt;Riskle&lt;/a&gt; (you'll need an &lt;a href=&quot;http://www.assembla.com/&quot;&gt;assembla&lt;/a&gt; account)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I put them in a particular path (&lt;code&gt;~/share/php/&lt;/code&gt;) which I add to my include path.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt;: Some &lt;a href=&quot;http://naneau.nl/&quot;&gt;dikdiks&lt;/a&gt; tend to store third-party in &lt;code&gt;application/library/&lt;/code&gt; instead of a completely separate place. This problem looks a lot like dynamically linked vs static binaries. With static binaries (in our case, storing all in &lt;code&gt;application/library/&lt;/code&gt;), you don't have to care about dependencies, as every single needed line of code is shipped with your application. This ease redistribution and installation a lot, but makes your download larger. You also have to manage yourself dependencies upgrade (which in turn save this hassle from the end-user). With dynamically linked applications, you avoid duplicated code by forcing the use of a global, site wide, code repository (generally &lt;code&gt;/usr/share/php&lt;/code&gt; on unix systems). You also transfer dependencies handling to the end-user (and/or the packaging system). Really, this is a choice to make yourself I think.&lt;/p&gt;


&lt;p&gt;Things get a little bit more complicated when the components does not follow the naming convention. What I do in this case is just puting them into a separate directory tree called &lt;code&gt;vendor/&lt;/code&gt;, which I don't forget to add to my include path of course, then I just manually includes need files. We could have done a one-to-one match between the component's public classes and custom &lt;em&gt;well-named&lt;/em&gt; classes, but it's much of a hassle for the benefit I think.&lt;/p&gt;


&lt;h3&gt;That's all folks !&lt;/h3&gt;

&lt;p&gt;Well that's all for today. I'll try to write some more in the future about application building with the Zend Framework, there are still a lot of things to be said, invented, and discovered :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2007/10/16/How-I-use-the-Zend-Framework#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2007/10/16/How-I-use-the-Zend-Framework#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/1070</wfw:commentRss>
      </item>
    
</channel>
</rss>