<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>David Reuss Feed</title>
    <link>http://davidreuss.github.com</link>
    <description>David Reuss</description>
    <pubDate>2009-05-18T21:03:25+02:00</pubDate>
    <lastBuildDate>2009-05-18T21:03:25+02:00</lastBuildDate>
    <webMaster>david@kompjuter.dk</webMaster>
	
	
 	<item>
   		<title>How (apparently!) not to do action based caching with Zend Framework</title>
   		<link>http://davidreuss.github.com/2009/05/17/how-not-to-do-action-based-caching-zf.html</link>
   		<guid>http://davidreuss.github.com/2009/05/17/how-not-to-do-action-based-caching-zf</guid>
   		<description>&lt;h1&gt;How (apparently!) not to do action based caching with Zend Framework&lt;/h1&gt;
&lt;p class=&quot;meta&quot;&gt;May 18th 2009&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve playing with &lt;a href=&quot;http://framework.zend.com&quot;&gt;Zend Framework&lt;/a&gt;. (ZF) for a personal project at the time, and there is a lot to like about ZF but you also have to realize it can be quite a monster to wrap your head around. Especially if you&amp;#8217;re dealing with the &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; package of the framework.&lt;/p&gt;
&lt;p&gt;The goal was to have access to easy action based caching, by utilizing any of the &lt;code&gt;Zend_Cache&lt;/code&gt; frontends. I&amp;#8217;d read a bit about the plugin infrastructure of ZF components and it seemed pretty standard.&lt;/p&gt;
&lt;p&gt;I figured an &lt;a href=&quot;http://framework.zend.com/manual/en/zend.controller.actionhelpers.html&quot;&gt;action helper&lt;/a&gt; helper extending &lt;a href=&quot;http://framework.zend.com/apidoc/core/Zend_Controller/Zend_Controller_Action_Helper/Zend_Controller_Action_Helper_Abstract.html&quot;&gt;&lt;code&gt;Zend_Controller_Action_Helper_Abstract&lt;/code&gt;&lt;/a&gt; would accomplish what i needed as it would give me &lt;em&gt;pre&lt;/em&gt; and &lt;em&gt;post&lt;/em&gt; dispatch hooks. The idea was just to hook into &lt;code&gt;postDispatch&lt;/code&gt;, and see if it&amp;#8217;s a registered method i want cached, and then store it away for the &lt;code&gt;preDispatch&lt;/code&gt; hook to look after on the nest request.&lt;/p&gt;
&lt;p&gt;Before actually implementing anything i whipped up a very simple helper for figuring out whether it did what i wanted or not.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Helper_ActionCache&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Zend_Controller_Action_Helper_Abstract&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;preDispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;postDispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$when&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$actionName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;strtoupper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getActionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
             &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;appendBody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$when&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$actionName&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;It&amp;#8217;s basically just a stupid logger that appends to the content of the page&lt;br /&gt;
so i&amp;#8217;d be able to figure out what time the hooks are run, and if i have access to the&lt;br /&gt;
content that i&amp;#8217;d like to cache.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&amp;gt; is prepended on &lt;code&gt;preDispatch&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&amp;lt; is prepended on &lt;code&gt;postDispatch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I had to perform a couple of tests to see if everything worked out in each of the different scenarios.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Plain action being called&lt;/li&gt;
	&lt;li&gt;Forwarding/rendering another action inside a controller&lt;/li&gt;
	&lt;li&gt;Nested actions &amp;#8211; calling an action inside another action&lt;/li&gt;
	&lt;li&gt;Action being called inside a viewscript&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So i wired stuff up, creating my &lt;code&gt;IndexController&lt;/code&gt; and my actions and noted the results on each of them.&lt;/p&gt;
&lt;h2&gt;The code&lt;/h2&gt;
&lt;h3&gt;controllers/IndexController.php&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IndexController&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Zend_Controller_Action&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$helper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;_helper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getHelper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;actionCache&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;indexAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;byrenderAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nestedAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;outerAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;innerAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;h3&gt;views/scripts/index.phtml&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Content...
&lt;/pre&gt;
&lt;/div&gt;&lt;h3&gt;views/scripts/nested.phtml&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;outer&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;h3&gt;views/scripts/outer.phtml&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;outer&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;h2&gt;Results&lt;/h2&gt;
&lt;h3&gt;1. Plain action being called (&lt;code&gt;index&lt;/code&gt;)&lt;/h3&gt;
&lt;pre class=&quot;terminal&quot;&gt;
&amp;gt; INDEX
&amp;lt; INDEX
Content...
&lt;/pre&gt;
&lt;p&gt;Um.. That was not exactly what i expected. And this was just for a plain action being called directly. Doesn&amp;#8217;t look good.&lt;/p&gt;
&lt;h3&gt;2. Forwarding/rendering another action inside a controller (&lt;code&gt;byrender&lt;/code&gt;)&lt;/h3&gt;
&lt;pre class=&quot;terminal&quot;&gt;
&amp;gt; BYRENDER
Content...
&amp;lt; BYRENDER
&lt;/pre&gt;
&lt;p&gt;Calling a plain action doesn&amp;#8217;t work, but rendering another action inside one does? Weird.&lt;/p&gt;
&lt;h3&gt;3. Nested actions &amp;#8211; calling an action inside another action (&lt;code&gt;nested&lt;/code&gt;)&lt;/h3&gt;
&lt;pre class=&quot;terminal&quot;&gt;
&amp;gt; NESTED
&amp;lt; NESTED
&amp;gt; INDEX
Content...
&amp;lt; INDEX
&amp;lt; INDEX
&lt;/pre&gt;
&lt;p&gt;What the heck is going on here? Nothing from the &lt;code&gt;outer&lt;/code&gt; action at all?&lt;/p&gt;
&lt;h2&gt;4. Action being called inside a viewscript (&lt;code&gt;outer&lt;/code&gt;)&lt;/h2&gt;
&lt;pre class=&quot;terminal&quot;&gt;
&amp;gt; OUTER
&amp;lt; OUTER
&amp;gt; INDEX
Content...
&amp;lt; INDEX
&lt;/pre&gt;
&lt;p&gt;Again. Confusing.&lt;/p&gt;
&lt;h2&gt;Failure&lt;/h2&gt;
&lt;p&gt;I set out creating a simple solution for action based caching with ZF and it seems as i&amp;#8217;ve failed miserably at doing it. Is the approach wrong? I&amp;#8217;m not sure. If the helper is not supposed to work like this (on plain actions) why is it seemingly invoked in the first place?&lt;/p&gt;
&lt;p&gt;If you have anything to say about this, please don&amp;#8217;t hesitate to leave a comment. I&amp;#8217;d love for this type of solution to work, as it seems like something really useful. Without a great deal of overhead. I know i will appreciate it very much.&lt;/p&gt;
&lt;p&gt;If it turns out this is indeed not intended behaviour i might give a shot at turning it into &lt;a href=&quot;http://en.wikipedia.org/wiki/Unit_testing&quot;&gt;unit tests&lt;/a&gt;, or even fixing it myself, if i&amp;#8217;d be able to fully comprehend the ZF &lt;a href=&quot;http://nethands.de/download/zenddispatch_en.pdf&quot;&gt;dispatch cycle&lt;/a&gt;.&lt;/p&gt;</description>
   		<pubDate>2009-05-17T00:00:00+02:00</pubDate>
 	</item>
 	
  </channel>
</rss>

