<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Juozas devBlog &#187; orm</title>
	<atom:link href="http://dev.juokaz.com/tag/orm/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.juokaz.com</link>
	<description>Random ideas, scripts and facts</description>
	<lastBuildDate>Mon, 22 Mar 2010 10:48:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Zend Framework and Doctrine. Part 3</title>
		<link>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3</link>
		<comments>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3#comments</comments>
		<pubDate>Mon, 30 Nov 2009 11:57:53 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=909</guid>
		<description><![CDATA[ During last two months I spent massive amount of time tweaking Doctrine ORM framework and making it to perform as fast as possible (as you might have noticed from my never ending tweets). This post is devoted to performance and efficiency, with practical tips &#038; tricks how to reduce memory usage, make it work [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/doctrine-orm-php5.png" alt="doctrine-orm-php5" title="doctrine-orm-php5" width="191" height="53" class="alignnone size-full wp-image-847" style="margin-right: 5px;" /> During last two months I spent massive amount of time tweaking Doctrine ORM framework and making it to perform as fast as possible (as you might have noticed from my never ending <a href="http://twitter.com/juokaz">tweets</a>). This post is devoted to performance and efficiency, with practical tips &#038; tricks how to reduce memory usage, make it work faster and save resources.</p>
<p>Doctrine is a very powerful framework, however you should study its behavior a little bit to get it working properly. As it turns out &#8211; it&#8217;s not that hard. </p>
<h5>Speed</h5>
<p>One of the first things I recommend looking at is <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/caching:query-cache-&#038;-result-cache">query cache</a>. Because there is quite a lot happening in turning <a href="http://www.doctrine-project.org/documentation/manual/1_2/nl/dql-doctrine-query-language">DQL</a> statement into the SQL query, <strong>caching</strong> that process can increase performance by a big margin. Best choice &#8211; <a href="http://en.wikipedia.org/wiki/PHP_accelerator">APC</a>, although robo47.net has an <a href="http://www.robo47.net/codeschnipsel/32-Adapter-fuer-Doctrine_Cache-zu-Zend_Cache">example</a> code for use of Zend_Cache adapters, just don&#8217;t forget that file back-end is probably not the best pick.</p>
<p><strong>Hydrators</strong> are probably the easiest thing to misuse. Hydration in Doctrine language is turning SQL query results into data graph. It can be an array, object or single value. It&#8217;s very nice to get results as PHP objects (in this case &#8211; models), however it&#8217;s slow. Slower than hydrating like array, and much slower than getting raw result from <a href="http://uk2.php.net/manual/en/book.pdo.php">PDO</a>. That&#8217;s why I always recommend answering one simple question: &#8220;will you be updating/deleting records?&#8221;. If the answer is no &#8211; hydrate as array, because you are not going to need an actual model (usually).</p>
<p>For this reason I always try to use array notation to access properties rather than like-object-vars one. Basically instead of <em>$product->name</em> I tend to write <em>$product['name']</em>, which returns the same result, but makes <strong>switching to array hydration very easy</strong>. You can find more tips and tricks at Doctrine manual <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/data-hydrators">here</a>, but the key moment is to remember that the faster data structure in PHP is array (I believe so), so if application is not performing well &#8211; start playing with hydrations first.</p>
<p>Doctrine has a very nice support for relations, where they work like proxies and data can be retrieved when it&#8217;s needed (lazy-loading). However, this is wrong:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Comments</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">print</span> <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">NewsItem</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This code is bad, because for each <em>comment</em> you will load <em>news item</em> using a <strong>separate query</strong>, hence you are wasting db server resources and making code slower. Optimization is pretty straightforward:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comments C'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">innerJoin</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C.NewsItem N'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C.user_id = ?'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">print</span> <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">NewsItem</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Here all the data is loaded in <strong>one query</strong> and everything happens much faster (and in this case making it to hydrate as array would also improve the performance).</p>
<p>However, make sure you <strong>know what you are joining</strong>. For example imagine that in previous example <em>news item</em> is also one-to-many (comment has many news items) relation and user <em>1</em> has written 1000 comments where each comment is attached to average <em>news items</em>. Query above will return 50&#8242;000 records (<a href="http://en.wikipedia.org/wiki/Cross_product">50 * 1000</a>) which Doctrine will need to hydrate then. This will be very slow and probably going to kill your web server after some time. One day I had a query which was returning 2GB of data, server admins where probably not very happy about it&#8230;</p>
<h5>Memory</h5>
<p>One of my favorite parts of software development is playing with memory usage and making it efficient. Even though it sounds really simple, debugging it and finding it where the memory is <a href="http://en.wikipedia.org/wiki/Memory_leak">leaking</a> is not an easy task. Recently I was using Doctrine to work with quite big datasets (on average 50&#8242;000 of records) and probably have tried all the possible tricks to make Doctrine memory efficient. My code looked really simple:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// do some work here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You might expect that memory usage would be steady, however it is not. Doctrine uses <a href="http://martinfowler.com/eaaCatalog/identityMap.html">identity map</a> and objects also have a lot of references which makes <strong>freeing up memory</strong> a tricky job. As my experience showed, even though records have a method <em>free()</em> which is supposed to de-reference it, sometimes it doesn&#8217;t help.</p>
<p>So to make memory management work, make sure to try these:</p>
<ul>
<li><strong>$record->free(true)</strong> &#8211; deep free-up, calls <em>free()</em> on all relations too</li>
<li><strong>$collection->free()</strong> &#8211; free all collection references</li>
<li><strong>Doctrine_Manager::connection()->clean()</strong> &#8211; cleanup connection (and remove identity map entries)</li>
</ul>
<p>With some debugging and profiling (and these methods) you hopefully can make memory usage to be low. I&#8217;m also using some custom iterators (available <a href="http://github.com/juokaz/php-examples/tree/master/doctrine-iterators/">here</a>) to <strong>divide query into chunks</strong>, because loading 50&#8242;000 of objects in one go is not going to work, so you might want to look at it too. </p>
<p>Another recommended tip: make sure to <strong>free queries</strong> too. As collections hold references to all records, query object also has some references to parsed sub-parts of query. For this I use auto-free setting enabled by (available in my first part post also <a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">here</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// enable automatic queries resource freeing</span>
<span style="color: #000088;">$manager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAttribute</span><span style="color: #009900;">&#40;</span>
	Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">ATTR_AUTO_FREE_QUERY_OBJECTS</span><span style="color: #339933;">,</span>
	<span style="color: #009900; font-weight: bold;">true</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>It&#8217;s very easy to forget to free a query and it&#8217;s again creating these references which makes <a href="http://php.net/manual/en/function.gc-enable.php">garbage collector</a>&#8217;s work hard. Nevertheless, after enabling this one I don&#8217;t know any other place where the memory can start to leak.</p>
<p>Last step &#8211; <strong>PHP 5.3</strong>. I&#8217;ve been working with this version for a few months and it works great, so if it&#8217;s possible &#8211; I recommend using it (you will also help with testing frameworks, but both Zend Framework and Doctrine already should work fine). One important function here is <a href="http://php.net/releases/5_3_0.php">improved</a> garbage collector, so the actual script takes less memory to execute. I haven&#8217;t recorded benchmarks on this one, but what I&#8217;ve noticed during development is that 5.3 does in fact has a lower peak memory usage. </p>
<h5>Conclusion</h5>
<p>I think I haven&#8217;t missed anything here, or at least these are the tips which made applications work fast (if I have &#8211; let me know). To finish with &#8211; good optimizations are done by comprehensive benchmarking and profiling, so the fact that Doctrine is a big framework doesn&#8217;t necessary mean it&#8217;s slow too. At the end of the day, it&#8217;s usually only a matter of reading a manual. </p>
<p><strong>All parts</strong>:</p>
<ol>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Zend Framework and Doctrine. Part 1</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2">Zend Framework and Doctrine. Part 2</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3">Zend Framework and Doctrine. Part 3</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Zend Framework and Doctrine. Part 2</title>
		<link>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2</link>
		<comments>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2#comments</comments>
		<pubDate>Wed, 18 Nov 2009 10:05:32 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[application.ini]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=866</guid>
		<description><![CDATA[Today we start actual development with Doctrine and Zend Framework. Base of this post is my code which I have been using for quite a few projects and it worked really well.
These are the steps required to setup Doctrine:

Create MySQL (or any other adapter supported by Doctrine) database
Download Doctrine 1.2 (as of today &#8211; 1.2.0beta3). [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/doctrine-orm-php5.png" alt="doctrine-orm-php5" title="doctrine-orm-php5" width="191" height="53" class="size-full wp-image-847" style="float: left; margin-right: 5px;" />Today we start actual development with Doctrine and Zend Framework. Base of this post is my code which I have been using for quite a few projects and it worked really well.</p>
<p>These are the steps required to setup Doctrine:</p>
<ol>
<li>Create MySQL (or any other adapter <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-connections">supported</a> by Doctrine) database</li>
<li>Download Doctrine 1.2 (as of today &#8211; <a href="http://www.doctrine-project.org/download/1_2_0_BETA3/format/tgz/package/">1.2.0beta3</a>). Believe, it&#8217;s stable enough (no problems at all for me) and supports functions all functions we are going to use later</li>
<li>Setup <em>application.ini</em> and <a href="http://framework.zend.com/manual/en/zend.application.quick-start.html#zend.application.quick-start.resources">application resource</a></li>
<li>Generate models from database</li>
<li>Profit!</li>
</ol>
<p>To start with, <strong>download</strong> this <a href="http://dev.juokaz.com/examples/doctrine/doctrine_v1.zip">archive</a> (or get updated version from my public <a href="http://github.com/juokaz/php-examples/tree/master/doctrine-application-resource/">repository</a>). It has everything you will need. Some of the files are quite long so I&#8217;m not going to post them here, it&#8217;s better that you download them and have them ready to be used as the article progresses. </p>
<h5>Create MySQL database</h5>
<p>For MySQL databases I use a product called &#8220;<a href="http://dev.mysql.com/downloads/workbench/5.1.html">MySQL Workbench</a>&#8220;. If you haven&#8217;t tried it I definitely recommend to give it a go &#8211; it basically allows you create a database as a <a href="http://forge.mysql.com/w/images/a/a8/Mysql_workbench_tbl_editor.png">diagram</a> and then export it to sql file or update actual database (can be risky). Since I expect you to have enough knowledge how to create a database I won&#8217;t write anything more &#8211; you can find <a href="http://www.webpronews.com/topnews/2005/06/06/mysql-for-beginners-how-to-create-a-mysql-database">tutorials</a> all over the web.</p>
<h5>Download Doctrine</h5>
<p>After downloading Doctrine extract it to <em>library</em> folder. You should have <em>./library/Doctrine.php</em> in your library folder. Although, you can use <em>svn:externals</em> (if you are using SVN at all) to remove Doctrine code from repository, but in this case you probably need to setup paths in application resource file explain below to use Doctrine_Core if you just get Doctrine folder contents (from <a href="http://svn.doctrine-project.org/tags/1.2.0-BETA3/lib/Doctrine/">here</a>).</p>
<p>Most important point here &#8211; don&#8217;t forget to <a href="http://www.doctrine-project.org/download">download</a> <strong>1.2</strong>, not version 1.1. Even though it doesn&#8217;t have a stable release, 1.1 doesn&#8217;t support models generation as we want them to be (auto-loadable). Also this week all bugs have been fixed which I reported and now models generation works perfectly. From my personal experience, I haven&#8217;t even used 1.1 at all (started with 1.2 when it was in alpha) and didn&#8217;t had any problems, so my recommendation &#8211; use 1.2. </p>
<h5>Setup application.ini and application resource</h5>
<p>From the file listed above open a file called <em>application.ini</em>. Append you current configuration (more on getting Zend Framework project running can be found <a href="http://framework.zend.com/docs/quickstart/create-your-project">here</a>) with settings in that file (leave compiled and cache options to false for now). Doctrine uses DNS strings to connect to a database, there are quite a few <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-connections#dsn,-the-data-source-name:examples">examples</a> in the documentation. If you have used <a href="http://php.net/manual/en/book.pdo.php">PDO</a> before you be very familiar.</p>
<p>In archive there is a file called <em>library/resource.php</em>. Depending on what namespace you use for outside-Zend code, paste it to chosen folder. If you choose to have &#8220;App&#8221; as a namespace, just copy that file to <em>library/App/Application/Resource/Doctrine.php</em>. And don&#8217;t forget to have:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">autoloaderNamespaces<span style="">&#91;</span><span style="">&#93;</span> <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;App_&quot;</span>
pluginpaths.App_Application_Resource <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;App/Application/Resource&quot;</span></pre></div></div>

<p>in <em>application.ini</em> also, otherwise library code won&#8217;t be auto-loaded. I don&#8217;t recommend putting any code in Zend folder, because it will create tons of problems in the future. Having App or ProjectName library folders allows to have your own code in separate packages which you can use in later projects (I usually have App, ProjectName, CompanyName). </p>
<p>Provided <em>application.ini</em> file isn&#8217;t that much configurable, mainly because it wasn&#8217;t supposed to be released at all. If you are looking for something more dynamic, look no further than this <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Application_Resource_Doctrine+-+Matthew+Lurz">proposal</a> in Zend incubator. Nevertheless, my code should work fine &#8211; it has all options required to get you started and have been tweaked with settings which I found to be really useful. </p>
<h5>Generate models from database</h5>
<p>This part is the most awesome. To start, just copy and paste everything from <em>scripts</em> folder in the zip archive to your scripts folder in application (I have scripts folder in the same level as application and library, in the root of project). There actually only two files &#8211; <em>doctrine-cli.php</em> and custom task in <em>Doctrine/Task/GenerateModels.php</em>. You can run doctrine-cli.php like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php doctrine-cli.php</pre></div></div>

<p>and you should get a list of <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/utilities#command-line-interface">all the possible tasks</a> (if you setup everything properly). To run my custom task, append &#8220;generate-models&#8221; to the end of previous command to get:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php doctrine-cli.php generate-models</pre></div></div>

<p>This task will load your database schema and create all classes (table, base model, model) required for models. Doctrine also supports generating models from <em><a href="http://en.wikipedia.org/wiki/YAML">yaml</a></em> configuration files, though I&#8217;ve never used it before, but configuration should be almost the same.</p>
<h5>It works</h5>
<p>To test the models you can look at the generate code or start coding you application (or even run <em><a href="http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language">dql</a></em> task from <em>doctrine-cli.php</em>). For example you can test simply like this (adjust by models you have):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$product</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model_Product<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Product name'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span>Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Model_Product'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If everything has been configured properly you shouldn&#8217;t get any errors and this code (put it in controller) should output array of your saved data. Because of the settings in application resource, save() method also runs <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/data-validation">validation</a> so if you missed a field and it breaks a <em>not null</em> constrain, this code will throw a validator exception. </p>
<h5>What&#8217;s next?</h5>
<p>This article has enough information to get you started and almost all the code provided it left as simple as possible and open for further modifications. I hope that in coming months code for Doctrine and Zend Framework integration will be completed and you can use Doctrine without any outside code.</p>
<p>Since we have application running now we can dive into actual usage, testing and more advanced stuff. I have code for these also and will be posting more articles very soon, even though the best resource for Doctrine is <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction">documentation</a>. If you have any problems with this code just leave a comment here or find my on twitter (<a href="http://www.twitter.com/juokaz">here</a>) and I will try to explain more.</p>
<p><strong>All parts</strong>:</p>
<ol>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Zend Framework and Doctrine. Part 1</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2">Zend Framework and Doctrine. Part 2</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3">Zend Framework and Doctrine. Part 3</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Zend Framework and Doctrine. Part 1</title>
		<link>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1</link>
		<comments>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1#comments</comments>
		<pubDate>Mon, 16 Nov 2009 14:09:07 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[domain model]]></category>
		<category><![CDATA[giorgio]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=845</guid>
		<description><![CDATA[If you are following twitter (you can find me there also) or any other social network, you might have noticed that there is a huge interest in Doctrine and Zend Framework integration. Since I&#8217;ve been using these libraries for quite a while now, so I&#8217;m going to explain some best practices and ways you can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/doctrine-orm-php5.png" alt="doctrine-orm-php5" title="doctrine-orm-php5" width="191" height="53" class="size-full wp-image-847" style="float: left; margin-right: 5px;" />If you are following twitter (you can find <a href="http://www.twitter.com/juokaz">me</a> there also) or any other social network, you might have noticed that there is a huge interest in Doctrine and Zend Framework integration. Since I&#8217;ve been using these libraries for quite a while now, so I&#8217;m going to explain some best practices and ways you can do that.</p>
<h5>History</h5>
<p>To start with, in my opinion, <a href="http://framework.zend.com/">Zend Framework</a> never had a proper M from <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a>. It was quite common to use <a href="http://framework.zend.com/manual/en/zend.db.table.html">Zend_Db_Table</a> as base models class, but it was simply not practical. When you start dealing with relations and hierarchical data types it starts to get really tricky, because simply Zend_Db_Table doesn&#8217;t provide an extensive enough functionality.</p>
<p>So half a year ago Zend Framework developers started to look for better solutions. Quite obvious one was to start implementing their own <a href="http://en.wikipedia.org/wiki/Domain_model">Domain</a> layer. You can find quite a few different implementations of that in <a href="http://www.google.co.uk/search?hl=en&amp;source=hp&amp;q=zend+framework+domain+model&amp;btnG=Google+Search&amp;meta=&amp;aq=1&amp;oq=zend+framework+domain+">blogosphere</a>, and I chose this path also. However, after quite some time of developing my own code I realized that it&#8217;s simply not a right thing to do &#8211; I&#8217;m expected to deliver a product and I was &#8220;wasting&#8221; way too much time tweaking, testing, extending etc. my domain model code.</p>
<p>So about 3-4 months ago I completely switched to <a href="http://www.doctrine-project.org/">Doctrine</a>. After evaluating possible solutions I decided to stay with Doctrine for a long time. I don&#8217;t know any other solution coming, I definitely don&#8217;t want (mainly because I don&#8217;t have time) to invest on creating my own library and Doctrine is simply awesome when you get used to it. After all this time I can say that it was a right call &#8211; Doctrine is on a way to being officially supported in Zend Framework (<a href="http://www.symfony-project.org/">Symfony</a> has it right now) and with Doctrine 2.0 (you can see a short presentation of its new features right <a href="http://www.slideshare.net/jwage/doctrine-2-enterprise-persistence-layer-for-php">here</a>) it will be just a perfect tools combination. I would very much agree with <a href="http://giorgiosironi.blogspot.com/2009/11/whats-going-on-with-php-object.html">Giorgio</a> that:</p>
<blockquote><p>Thus, Doctrine 2 is going to become <strong>the first production-ready Orm for php</strong> and to be favored with seamless integration in both <a href="http://framework.zend.com/">Zend Framework</a> and <a href="http://www.symfony-project.org/">Symfony</a>.</p></blockquote>
<h5>Benefits</h5>
<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/04/logo-zend-framework.jpg" alt="Zend framework" title="Zend framework" width="141" height="95" class="size-full wp-image-460" style="float: right; margin-left: 5px;" /> Some time ago I was actually involved in making a decision of choosing Doctrine over other libraries (main Zend Framework components) as part of my work, so here I&#8217;m going to outline some points which made that decision easier. </p>
<p><strong>Relations</strong>. I keep repeating this term every time I speak about Doctrine (or ORM&#8217;s in general), but for me it&#8217;s a key factor in writing code fast. Quick example: let&#8217;s image that our application consists of Order which has a list of Items where Item is Product and price, quantity information. Code for this situation:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Order<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$item</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> OrderItem<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$product</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// product object from somewhere</span>
<span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">quantity</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">price</span> <span style="color: #339933;">=</span> <span style="color:#800080;">9.99</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Items</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is how much code I need to write myself. I&#8217;m going to show more examples in the future posts, but because Doctrine is ORM (object relation mapper) all the hierarchical structure of your application data becomes very easy to work with.  </p>
<p>What is more, Doctrine can <strong>generate</strong> all the <strong>model classes</strong> by itself. Now that&#8217;s a treasure! Just specify database connection in the config file, open up a terminal and run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php doctrine-cli.php generate-models-db</pre></div></div>

<p>In a few seconds all schema information is retrieved from the actual database and all the classes are created. My biggest project so far with Doctrine was worth more than 10&#8242;000 lines of models code. I don&#8217;t know how to count the time it saved and despite a few minor bugs in Doctrine library it worked exactly as we wanted.</p>
<p>I can list things I like about it for hours probably, so I&#8217;m going to finish this list with the future I consider to be a very big time saver. This feature is dynamics of models: <strong>inheritance</strong> and <strong>behaviors</strong>. Inheritance makes your objects have different classes even though they could be a same table (with for example <a href="http://www.doctrine-project.org/documentation/manual/1_1/en/inheritance#column-aggregation">type_id</a>). All the work needed to handle the actual schema is done in background.</p>
<p>Behaviors work in the same way &#8211; one line of code and a model becomes physically undeletable (called <a href="http://www.doctrine-project.org/documentation/manual/1_1/en/behaviors#core-behaviors:softdelete">soft-delete</a>) or has a separate table to save revisions. Behaviors are very similar to decorators in Zend_Form for example &#8211; they are small classes which can be added to the main class to extend its functionality. So in the end your mode could have all sorts of different functionality depending on how you &#8220;decorate&#8221; it.</p>
<h5>What&#8217;s next?</h5>
<p>I only wrote a few examples how great Doctrine actually is today, but you can expect a lot more. Especially in Zend Framework code side: application.ini settings, application resource to setup auto-loading, script to generate Zend Framework compatible models, testing Doctrine models and much more. I&#8217;m also involved in a work group making Doctrine and Zend Framework integration possible so you can expect great things to come (first proposal <a href="http://framework.zend.com/wiki/display/ZFPROP/Doctrine+1+and+Zend_Tool+Integration+-+Benjamin+Eberlei">here</a>).</p>
<p><em>If you have been following me on twitter you might have noticed that I tweet a lot of interesting material on both Zend Framework, Doctrine and general PHP so I would recommend following me there or subscribing to the RSS </em><a href="http://dev.juokaz.com/feed"><em>feed</em></a><em>. I haven&#8217;t been writing for a while now, but I will try as hard as I can to change it and write much more frequently &#8211; during past months I tried a lot of cool stuff which I would love to talk about.</em></p>
<p><strong>All parts</strong>:</p>
<ol>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Zend Framework and Doctrine. Part 1</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2">Zend Framework and Doctrine. Part 2</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3">Zend Framework and Doctrine. Part 3</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
