<?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>stevehollis.com &#187; Zend Framework</title>
	<atom:link href="http://www.stevehollis.com/tag/zend-framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stevehollis.com</link>
	<description>Barking on about PHP, MySQL and Zend Framework</description>
	<lastBuildDate>Mon, 05 Apr 2010 18:07:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Super-Skinny your Zend Framework Action Controllers (Part One)</title>
		<link>http://www.stevehollis.com/2010/03/super-skinny-your-zend-framework-action-controllers-part-one/</link>
		<comments>http://www.stevehollis.com/2010/03/super-skinny-your-zend-framework-action-controllers-part-one/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 09:50:18 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[action helper]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[zend_controller_action]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.stevehollis.com/?p=53</guid>
		<description><![CDATA[Inspired by Padraic Brady&#8217;s post on Fat Stupid Ugly Controllers and Chris Hartjes&#8217; Fat Models, Skinny Controllers, I&#8217;ve been putting my controllers on a crash diet. Slim controllers are easier to test, encourage the DRY principle and force business logic back into the model layer where it belongs. In this first article, I&#8217;ll be looking [...]]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_101" class="wp-caption alignright" style="width: 310px"><a href="http://www.stevehollis.com/wp-content/uploads/2010/03/scales.jpg"><img src="http://www.stevehollis.com/wp-content/uploads/2010/03/scales.jpg" alt="Super Skinny Your Controllers" title="Super Skinny Your Controllers" width="300" height="301" class="size-full wp-image-101" /></a><p class="wp-caption-text">Lose pounds of excess code in 1 easy step!</p></div>Inspired by Padraic Brady&#8217;s post on <a href="http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html">Fat Stupid Ugly Controllers</a> and Chris Hartjes&#8217; <a href="http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/">Fat Models, Skinny Controllers</a>, I&#8217;ve been putting my controllers on a crash diet.</p>
<p>Slim controllers are easier to test, encourage the <acronym title="Don't Repeat Yourself">DRY</acronym> principle and force business logic back into the model layer where it belongs.</p>
<p>In this first article, I&#8217;ll be looking at a quick way to de-bloat Zend Framework Action Controllers by using an Action Helper to automatically instatiate models and assign them to properties in the controller and view.</p>
<h3>Lather, Rinse, Repeat</h3>
<p>Controller actions often perform mundane, repetitive tasks. Checking for required parameters, creating objects and assigning variables (again and again) eats up line after line of code in a typical controller. </p>
<p>Using the address book example, a simple action in our Contact controller might look something like this:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ContactController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> viewAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// check that we have a contact ID, otherwise redirect to index</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_hasParam<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'id'</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span>Contact<span style="color: #339933;">::</span><span style="color: #004000;">exists</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getParam<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'id'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">FlashMessenger</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'No contact specified or contact does not exist.'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_redirect<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'contact'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// lookup and instantiate the contact object</span>
	<span style="color: #000088;">$contact</span> <span style="color: #339933;">=</span> Contact<span style="color: #339933;">::</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getParam<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'id'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// assign contact to view</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">contact</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$contact</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>A few things are happening here:</p>
<ol>
<li>First, we check to see if the &#8216;id&#8217; param exists in the request.</li>
<li>Then we use our model&#8217;s static exists() method to check that the contact ID corresponds to a real contact.</li>
<li>The contact object is then looked up using a static finder method.</li>
<li>&#8230;and finally we assign the contact to the view.</li>
</ol>
<p>The exact code will vary depending on your model implementation, but this sort of process is pretty typical in my experience. In many actions, that&#8217;s all that&#8217;s required: the view then does its thing on the contact object that it&#8217;s been given.</p>
<p>Pretty boring stuff and chances are some or all of the above will be repeated in a handful of other actions in the same controller. That&#8217;s a &#8220;code smell&#8221; if ever I smelled one.</p>
<p>By automating these repetitive operations, there&#8217;s an opportunity to substantially reduce the size of our controllers without losing any functionality.</p>
<h3>The Action Helper</h3>
<p>Fortunately, Zend Framework has the perfect tool for this kind of job: an Action Helper.</p>
<p>By tapping into the preDispatch() hook provided and making a few basic assumptions, we can look for models specified in the request, instantiate them and then assign them to properties in both the action controller and the view. </p>
<p>Here&#8217;s the basic action helper class, which I&#8217;ve called &#8220;ModelWatcher&#8221;:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Dog_Zend_Controller_Action_Helper_ModelWatcher <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action_Helper_Abstract
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * @var string
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_controllerName</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> preDispatch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_controllerName <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getControllerName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_view <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_actionController<span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">;</span>
&nbsp;
	try <span style="color: #009900;">&#123;</span>
	    <span style="color: #000088;">$model</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getModel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	    <span style="color: #666666; font-style: italic;">// assign to the controller and view</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_actionController<span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_controllerName<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$model</span><span style="color: #339933;">;</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_view<span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_controllerName<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$model</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span> Exception <span style="color: #000088;">$e</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @return object The instantiated model object
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> _getModel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900; font-weight: bold;">NULL</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParam</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'id'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;ID parameter not found in request&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParam</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'id'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// attempt to find and instantiate the model object</span>
	<span style="color: #000088;">$modelClass</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_controllerName <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$model</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modelClass</span><span style="color: #339933;">::</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$id</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$model</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p><strong>Important:</strong> Don&#8217;t forget that you&#8217;ll need to add the helper to your bootstrap for this to work. Something like this should do the trick:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Zend_Controller_Action_HelperBroker<span style="color: #339933;">::</span><span style="color: #004000;">addHelper</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Dog_Zend_Controller_Action_Helper_ModelWatcher<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></code></p>
<p>When the helper&#8217;s preDispatch() method is called, it checks the request for the &#8220;id&#8221; parameter and attempts to find and create the model object. In the case of our address book, a request URL like <em>http://www.example.com/contact/id/123</em> would try to retrieve an object of the class Contact whose ID is 123. </p>
<p>We wrap the call to _getModel() in a try&#8230;catch block to deal with two scenarios: </p>
<ol style="list-style-type:decimal;">
<li>When no ID parameter exists in the request or</li>
<li>No record exists for the given ID</li>
</ol>
<p>The latter assumes that the find() method will throw an exception if the record is not found. </p>
<p>If the lookup is successful, the newly created object is assigned to the controller and view with a property named after the controller. So with our address book example, you&#8217;d access the contact object using $this->contact from within both the controller and the view. </p>
<p>On failure, we do nothing &#8211; leaving the action controller to implement its own logic for dealing with non-existent objects.</p>
<h3>The Final Weigh-In</h3>
<p>All this means we&#8217;re left with a significantly slimmer controller action:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ContactController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> viewAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// check that we have a contact object</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">contact</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">FlashMessenger</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'No contact specified or contact does not exist.'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_redirect<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'contact'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
The controller action now only needs to check that a contact object has been created by the action helper. There&#8217;s no need for it to get its hands dirty with the request params, object generation or assigning variables to the view as it&#8217;s already been done.</p>
<p>This approach does require an adherence to some naming conventions&#8230; primarily that the model class name has to mirror the controller name and the identifying parameter is always passed as &#8220;id&#8221; in the URL. Provided they aren&#8217;t too wacky, it should be reasonably easy to re-jig the code to suit any conventions of your own.</p>
<h3>Further Weight Loss</h3>
<p>A slightly more flexible approach is to use verbose ID parameters like &#8220;contact-id&#8221;. This gives you the ability to have model classes which don&#8217;t match the controller name and also allows multiple models to be instantiated by the ModelWatcher in one request, both of which can be useful. I use something similar in my own implementation.</p>
<p>You might also want to consider adding other logic in to the ModelWatcher helper like record locking or fine-grained access control. Even if you decide to separate these activities into a separate helper class, you can still use the models inserted into the controller rather than going back to the request parameters again. Just make sure that the ModelWatcher is added to the action helper plugin stack before any helper that relies on it or the models it creates.</p>
<h3>Final Thoughts</h3>
<p>Hopefully it should be fairly clear that this simple action helper has the potential to dramatically reduce the amount of boiler plate code in your controllers. Eagle-eyed readers might also have noticed that automatically assigning models to the controller is a feature of <a href="http://book.cakephp.org/view/53/components-helpers-and-uses">CakePHP</a>.</p>
<p>Look out for future posts where I&#8217;ll be discussing more ways to de-clutter and cut down your controllers.</p>
<p>P.S. Thanks to <a href="http://www.zendframeworkinaction.com/2010/03/05/steve-hollis-blog-practical-nested-transactions-with-zend_db-and-mysql/">Rob Allen</a>, <a href="http://weierophinney.net/matthew/">Matthew Weier O&#8217;Phinney</a>, <a href="http://blog.astrumfutura.com/">Pádraic Brady</a>, <a href="http://blog.ekini.net/2010/03/05/zend-framework-how-to-use-nested-transactions-with-zend_db-and-mysql/">Wenbert Del Rosario</a> and others for retweeting/linking to my <a href="http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/">first post</a> <img src='http://www.stevehollis.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevehollis.com/2010/03/super-skinny-your-zend-framework-action-controllers-part-one/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Practical Nested Transactions with Zend_Db and MySQL</title>
		<link>http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/</link>
		<comments>http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 16:05:35 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[transactions]]></category>
		<category><![CDATA[zend_db]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.stevehollis.com/?p=35</guid>
		<description><![CDATA[The need to save dependent or child models appears frequently in object oriented applications. In such cases, it&#8217;s usually desirable to group all the save operations for a parent and its children into a single atomic transaction. Many RDBMS brands support transactions, but few can handle these kind of &#8220;nested&#8221; transactions. This article discusses how [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.stevehollis.com/wp-content/uploads/2010/03/firebug1.png"><img class="alignright size-full wp-image-45" title="Debugging Zend_Db with Firebug" src="http://www.stevehollis.com/wp-content/uploads/2010/03/firebug1.png" alt="Debugging Zend_Db with Firebug" width="300" height="192" /></a>The need to save dependent or child models appears frequently in object oriented applications. In such cases, it&#8217;s usually desirable to group all the save operations for a parent and its children into a single atomic transaction. Many RDBMS brands support transactions, but few can handle these kind of &#8220;nested&#8221; transactions.</p>
<p>This article discusses how to extend Zend_Db_Adapter to give the illusion of nested transactions &#8211; a handy workaround for use in object oriented applications. Although I focus on MySQL, it should be possible to apply these concepts to any other database flavour which supports transactions. There are some limitations to this approach, but I&#8217;ve found it to be very useful in practice.</p>
<h3>A Brief Introduction to Transactions</h3>
<p>You can&#8217;t work with database backed web apps for very long without coming across the concept of database transactions.</p>
<p>Transactions (<a href="http://en.wikipedia.org/wiki/Database_transaction">http://en.wikipedia.org/wiki/Database_transaction</a>) are a way of encapsulating a group of database queries, typically INSERT and UPDATE statements, so that they all must complete successfully in order for the changes to be written (&#8220;committed&#8221;) to the database. If any single query fails, any changes to the database can be &#8220;rolled back&#8221; to how they were when the transaction began.</p>
<p>This has great practical value. Many operations consist of several steps where the changes should only be applied if every step is successful. The classic example is transferring funds between two bank accounts, which is a three stage process:</p>
<ol>
<li>Checking that the sender&#8217;s account has a balance greater than the amount to be transferred.</li>
<li>Subtracting that amount from the sender&#8217;s account</li>
<li>And, finally, adding it to the recipient&#8217;s account.</li>
</ol>
<p>The SQL for this transaction might go something like:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">START</span> <span style="color: #990099; font-weight: bold;">TRANSACTION</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">SELECT</span> balance <span style="color: #990099; font-weight: bold;">FROM</span> account <span style="color: #990099; font-weight: bold;">WHERE</span> account_number <span style="color: #CC0099;">=</span> <span style="color: #008080;">123456789</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">UPDATE</span> account <span style="color: #990099; font-weight: bold;">SET</span> balance <span style="color: #CC0099;">=</span> balance <span style="color: #CC0099;">-</span> <span style="color: #008080;">100.00</span> <span style="color: #990099; font-weight: bold;">WHERE</span> account_number <span style="color: #CC0099;">=</span> <span style="color: #008080;">123456789</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">UPDATE</span> account <span style="color: #990099; font-weight: bold;">SET</span> balance <span style="color: #CC0099;">=</span> balance <span style="color: #CC0099;">+</span> <span style="color: #008080;">100.00</span> <span style="color: #990099; font-weight: bold;">WHERE</span> account_number <span style="color: #CC0099;">=</span> <span style="color: #008080;">987654321</span><span style="color: #000033;">;</span>
<span style="color: #990099; font-weight: bold;">COMMIT</span><span style="color: #000033;">;</span></pre></div></div>

<p></code><br />
If an error is thrown at any point in the process, the ROLLBACK statement can be used to revert the database to its state before the transaction began.</p>
<p>In an application that doesn&#8217;t use transactions, a typical approach might be to check the return value of each query or enclose it in a try&#8230;catch block:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$balance</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchOne</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;SELECT `balance` FROM `account` WHERE `account_number` = 123456789&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'account'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'balance'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Db_Expr<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;`balance` + 100&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;`account_number` = 123456789&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'account'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'balance'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Db_Expr<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;`balance` - 100&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;`account_number` = 987654321&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span> Zend_Db_Exception <span style="color: #000088;">$e</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
The problem with this approach is that although we know the operation failed, we don&#8217;t know <strong>when</strong> it failed. Perhaps the first update statement was executed, but the second one wasn&#8217;t. Perhaps the database connection was lost before we even started. The end result is that we may have introduced inconsistencies into our data that, even with this simple example, are going to be hard to track down and correct.</p>
<p>Using transactions we can ensure that each step is carried out successfully or the whole operation fails.<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$balance</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchOne</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;SELECT `balance` FROM `account` WHERE `account_number` = 123456789&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'account'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'balance'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Db_Expr<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;`balance` + 100&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;`account_number` = 123456789&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'account'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'balance'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Db_Expr<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;`balance` - 100&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;`account_number` = 987654321&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span> Zend_Db_Exception <span style="color: #000088;">$e</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollBack</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000088;">$e</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
By calling the beginTransaction() method, we temporarily delay any actual modifications to the database. If each query is successful, the changes are committed using the commit() method. But if an exception is thrown, the changes are reverted using rollback().</p>
<h3>The Problem</h3>
<p>Although transactions are a useful tool, sadly they don&#8217;t always fit well into an object oriented application.</p>
<p>It&#8217;s common to delegate the actual persistence (inserting and updating) of models to a save method which, in turn, goes on to save child objects. Say we have a simple address book application which allows you to enter multiple notes for each contact. The save method for the Contact model might look something like this:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_db<span style="color: #339933;">;</span>
&nbsp;
    try <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #666666; font-style: italic;">// new model</span>
	    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">insert</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'contact'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #666666; font-style: italic;">// existing model</span>
	    <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'contact'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">quoteInto</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'`id` = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// save the contact's note</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNotes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$note</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    <span style="color: #000088;">$note</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>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span> Zend_Db_Exception <span style="color: #000088;">$e</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollBack</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">throw</span> <span style="color: #000088;">$e</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
The save method for the Note class is similar, starting a transaction and saving the individual note.</p>
<p>Herein lies the problem: <strong>attempting to start an new transaction implicitly commits the current transaction</strong> (<a href="http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html">http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html</a>). Without ugly hacks which tie the models directly to the database operations, it becomes difficult to establish which object started the transaction and when it should be committed.</p>
<h3>The Solution</h3>
<p><em>Disclaimer: This solution is adapted from the extended Pdo_MySql adapter in Varien&#8217;s Magento e-commerce product. A similar approach is adopted by Bryce Lohr&#8217;s <a title="Nested Table Support" href="http://framework.zend.com/wiki/display/ZFPROP/Nested+Transaction+Support+for+Zend_Db_Adapter_Abstract+-+Bryce+Lohr" target="_blank">Nested Table Support</a> for Zend_Db proposal. You should read Bill Karwin&#8217;s comments about that proposal and understand the limitations of this method before implementing it. <strong>That said</strong>, I still believe this is a useful and practical way of simulating nested transactions and I have used it a number of times.</em></p>
<p>A simple solution to the problem is to keep track of the &#8220;depth&#8221; of the transaction, that is, how many times the beginTransaction() method has been called. That way, we can hold off committing the changes to the database until we are certain that all the save operations have completed successfully.</p>
<p>Since transactions apply to the whole database connection, the most logical place to manage this process is in the DB adapter class. To do this, we extend our adapter class like so:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> App_Zend_Db_Adapter_Mysqli <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Adapter_Mysqli
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Current Transaction Level
     *
     * @var int
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_transactionLevel</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Begin new DB transaction for connection
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> beginTransaction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            parent<span style="color: #339933;">::</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel<span style="color: #339933;">++;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Commit DB transaction
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> commit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel <span style="color: #339933;">===</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            parent<span style="color: #339933;">::</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel<span style="color: #339933;">--;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Rollback DB transaction
     *
     * @return App_Zend_Db_Adapter_Mysqli
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> rollback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel <span style="color: #339933;">===</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            parent<span style="color: #339933;">::</span><span style="color: #004000;">rollback</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel<span style="color: #339933;">--;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Get adapter transaction level state. Return 0 if all transactions are complete
     *
     * @return int
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getTransactionLevel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_transactionLevel<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
Update your bootstrap to use the extended class et voila &#8211; a single START TRANSACTION and COMMIT or ROLLBACK is sent to MySQL, regardless of how many levels of nested pseudo-transactions have been created.</p>
<p><strong>Please Note:</strong></p>
<ul>
<li>It&#8217;s important that each child save() method re-throws the exception so that transaction depth is reduced by successive calls to rollBack(). The end result is that the originally called save() method then performs the actual rollback.</li>
<li>All the tables used in the transaction <strong>must</strong> use a storage engine that supports transactions. For MySQL, this will most likely mean using InnoDB. To convert a MyISAM or other table type to InnoDB, use &#8220;ALTER TABLE table ENGINE = InnoDB&#8221;. It could take some time to rebuild the indexes on large tables. There are other considerations about the use of InnoDB &#8211; please consult the MySQL manual.</li>
<li>If the tables used don&#8217;t support transactions, it&#8217;ll just fail silently. Bad times. I highly recommend using Firebug and Zend_Db_Profiler to monitor database queries during development (see <a href="http://framework.zend.com/manual/en/zend.db.profiler.html">http://framework.zend.com/manual/en/zend.db.profiler.html</a>);</li>
</ul>
<p>I hope you find the above useful &#8211; if so, please leave a comment. If not, please be gentle&#8230; it&#8217;s my first blog post!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Blimey! I&#8217;ve got a blog!</title>
		<link>http://www.stevehollis.com/2010/03/blimey-ive-got-a-blog/</link>
		<comments>http://www.stevehollis.com/2010/03/blimey-ive-got-a-blog/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 13:19:31 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[zend_application]]></category>
		<category><![CDATA[zend_db]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.stevehollis.com/?p=25</guid>
		<description><![CDATA[To be honest, I&#8217;m a bit ashamed. I&#8217;ve been working with web development and internet marketing for almost half a decade and only now, in 2010 for Christ&#8217;s sake, have I got round to starting a blog. There are plenty of excuses: haven&#8217;t had the time, I thought it might be tricky to set up, didn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_28" class="wp-caption alignright" style="width: 310px"><a href="http://www.stevehollis.com/wp-content/uploads/2010/03/CIMG25902.jpg"><img class="size-medium wp-image-28  " title="Meeko in full flight" src="http://www.stevehollis.com/wp-content/uploads/2010/03/CIMG25902-300x205.jpg" alt="Meeko in full flight" width="300" height="205" /></a><p class="wp-caption-text">Gratuitous and unnecessary dog picture (Pic: Steven Jack)</p></div>
<p>To be honest, I&#8217;m a bit ashamed.</p>
<p>I&#8217;ve been working with web development and internet marketing for almost half a decade and only now, in 2010 for Christ&#8217;s sake, have I got round to starting a blog.</p>
<p>There are plenty of excuses: haven&#8217;t had the time, I thought it might be tricky to set up, didn&#8217;t need another codebase to get to grips with. But frankly, they&#8217;re all pretty pathetic.</p>
<p>As it happens, I&#8217;ve been amazed by just how easy it&#8217;s been to set up a WordPress blog. I bought this snazzy, clean theme and had it all up and running on my Windows dev server in about 5 mins. Transferring it to my cluster took a little more effort, but the whole thing has only taken a few hours, and most of that was browsing through different themes.</p>
<p>Anyway, I&#8217;m here now, so let&#8217;s look to the future.</p>
<p>The plan is to blog about the trickier issues that I come across working as a web developer. So you can mainly expect stuff relating to PHP, MySQL and Zend Framework. I wouldn&#8217;t be at all surprised if there ends up being a smattering of Apache, jQuery and server admin posts too.</p>
<p>The inspiration, if you can call it that, is a pretty selfish one. I&#8217;ve recently been working on Entertainment Manager, an &#8220;enterprise-level&#8221; business management tool for Entertainment Agencies (which I&#8217;ll blog about at a later date). Inevitably, I&#8217;ve stumbled into a few issues where it&#8217;s been tough to find any real solutions online.  It may be because PHP is a relative new comer as an &#8221;enterprise&#8221; (I hate that term) language, or just because some of the terminology gets a bit vague when dealing with more complex problems.</p>
<p>In any case, the aim of this blog is to document these thorny problems and their solutions so that I have something to refer to in the future when I&#8217;ve forgotten all the details (like next week&#8230; OK, tomorrow). It&#8217;d be a massive bonus if other people could benefit from my experience and save themselves a few hours of head scratching in the process.</p>
<p>There&#8217;s a real danger that I won&#8217;t post often enough and that the quality of the content may be, um, variable. But, hey, it&#8217;s taken me five years to get to this point, so give me a break, eh?</p>
<p>There are a handful of issues on the to-blog list at the moment:</p>
<ul>
<li>Nested transactions using Zend_Db (<a href="http://www.stevehollis.com/2010/03/practical-nested-transactions-with-zend_db-and-mysql/">done</a>)</li>
<li>Plugin functionality for models</li>
<li>Practical Model/Resource (i.e. DB) separation</li>
<li>&#8220;Real&#8221; modular bootstrapping with Zend_Application</li>
<li>How to make your models fatter and your controllers thinner (<a href="http://www.stevehollis.com/2010/03/super-skinny-your-zend-framework-action-controllers-part-one/">Part One</a>)</li>
</ul>
<p>Hopefully I&#8217;ll come up with something of interest so you&#8217;ll be back soon.</p>
<p>Steve</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevehollis.com/2010/03/blimey-ive-got-a-blog/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

