<?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>CWD - Customized Web Development &#187; Zend Framework</title>
	<atom:link href="http://www.cwd.at/category/blog/php/zend_framework-php-blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cwd.at</link>
	<description></description>
	<lastBuildDate>Fri, 30 Oct 2009 00:27:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Zend Framework 1.9.0 Preview Release</title>
		<link>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/</link>
		<comments>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 09:09:58 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/</guid>
		<description><![CDATA[Zend hat gestern Abend die Preview von Zend Framework 1.9 freigegeben. http://devzone.zend.com/article/4846]]></description>
			<content:encoded><![CDATA[<p>Zend hat gestern Abend die Preview von Zend Framework 1.9 freigegeben.<br />
<a href="http://devzone.zend.com/article/4846" target="_blank">http://devzone.zend.com/article/4846</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 1.8.2 erschienen</title>
		<link>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/</link>
		<comments>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/#comments</comments>
		<pubDate>Thu, 28 May 2009 07:07:01 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=125</guid>
		<description><![CDATA[Gestern ist Zend Framework 1.8.2 erschienen. Changelog findet sich hier. Mein persönliches Highlight: Zend_Db_Table und Joins arbeiten endlich wie sie sollen.]]></description>
			<content:encoded><![CDATA[<p>Gestern ist Zend Framework 1.8.2 erschienen. <a href="http://framework.zend.com/changelog" target="_blank">Changelog findet sich hier.</a></p>
<p>Mein persönliches Highlight: Zend_Db_Table und Joins arbeiten endlich wie sie sollen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Caching Zend_Db_Table Models</title>
		<link>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/</link>
		<comments>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/#comments</comments>
		<pubDate>Mon, 18 May 2009 18:27:00 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=100</guid>
		<description><![CDATA[(Dieser Artikel ist ausnahmsweise in Englisch) Have you ever felt the need to cache Databaseresults ? Of course you have. Do you also use Zend_Db_Table for the less complex queries ? Then this may be interesting for you. Of course, these simple queries would easily fit in MySQL (or any other DB) query cache. But [...]]]></description>
			<content:encoded><![CDATA[<p>(Dieser Artikel ist ausnahmsweise in Englisch)</p>
<p>Have you ever felt the need to cache Databaseresults ? Of course you have. Do you also use Zend_Db_Table for the less complex queries ? Then this may be interesting for you.</p>
<p><span id="more-100"></span>Of course, these simple queries would easily fit in MySQL (or any other DB) query cache. But maybe you want to save this for your complex queries building Tmp-Tables in MEMORY. Or for whatever reason, here is a solution.</p>
<p>You find the full <a href="http://svn.cwd.at/cwd/trunk/Cwd/" target="_blank">classes on my svn.</a></p>
<p>The basic idea is from <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models" target="_blank">Pascal Opitz</a> with contributions from <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models#comment-5876" target="_blank">Robert Kummer</a> and <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models#comment-5935" target="_blank">Sascha-Oliver Prolic</a>. Their version is great but does not work with Zend_Db_Table.</p>
<p>Let&#8217;s start with extending Zend_Db_Table_Abstract:</p>
<pre><code class="php">
abstract class Cwd_Db_Table extends Zend_Db_Table_Abstract {
	/**
	 * @var Cwd_Db_Cache
	 */
	public $cache;

	protected $_rowClass ='Cwd_Db_Table_Row';

	public function __construct($config=array()) {
		parent::__construct($config);
		/**
		 * @var Cwd_Db_Cache
		 */
		$this-&gt;cache = new Cwd_Db_Cache($this);
	}
}
</code></pre>
<p>We just add the cache to it and set the protected var $_rowClass, this is needed because we want the results to be of our own implementation of Zend_Db_Table_Row_Abstract.</p>
<p>Our implementation looks like this:</p>
<pre><code class="php">
class Cwd_Db_Table_Row extends Zend_Db_Table_Row_Abstract {
	/**
	 * @var Cwd_Db_Cache
	 */
	public $cache;

	public function __construct($config=array()) {
		parent::__construct($config);

		$this-&gt;cache = new Cwd_Db_Cache($this);
	}

	public function setTable(Zend_Db_Table_Abstract $table = null)
    {
        if ($table == null) {
            $this-&gt;_table = null;
            $this-&gt;_connected = false;
            return false;
        }

        $tableClass = get_class($table);

        /**
        // we lost $this-&gt;_tableClass, so this would throw always an exception
		// we have to ignore this for now.

        if (! $table instanceof $this-&gt;_tableClass) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this-&gt;_tableClass");
        }
		*/

        $this-&gt;_table = $table;
        $this-&gt;_tableClass = $tableClass;

        $info = $this-&gt;_table-&gt;info();

        if ($info['cols'] != array_keys($this-&gt;_data)) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row');
        }

        if (! array_intersect((array) $this-&gt;_primary, $info['primary']) == (array) $this-&gt;_primary) {

            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row");
        }

        return true;
    }	

    /**
     * Set the table
     * this is necessary if the row lies in cache
     *
     * also we aresetting automatically a cache suffix
     *
     * @param $table Zend_Db_Table_Abstract A instance of a model.
     */
    public function prep($table){
    	$this-&gt;setTable($table);
        $table=$this-&gt;getTable()-&gt;info();
        $tablename=$table['name'];
        $primary=$table['primary'][1];

        $this-&gt;cache-&gt;setCacheSuffix($tablename.'__'.$this-&gt;$primary.'__');
    }
}
</code></pre>
<p>Ok, what did we do. We have our cache in it, and are overwriting the setTable method.  If the row is stored in the cache, we lose _tableClass, and the only way to set it right again is to use the setTable method, but unfortunatly this method is checking if the table object we give to it is the same as the object in _tableClass &#8230; you see the problem. So we have to overwrite this only to comment this part out.</p>
<p>At the bottom you see a new prep method. This method calls the setTable method and also sets a cache suffix. This is needed becouse the Zend_Cache_Frontend_Class generates the id only by method name and parameters, but not on contents of the object. So if you have a loop and for example use findParentRow() in it, you would get the same row for every  Query from the cache. This is not what we want. So we autoextend the cache suffix by the primary key column with the value of the primary key. (in the current version, there is no check if the primary key has more than one field. If you need this feel free to overwrite/extend my class)</p>
<p>To make use of these classes you just have to build your models by extending Cwd_Db_Table instead of Zend_Db_Table_Abstract.</p>
<p>If you have done so, you can use it like in the following example:</p>
<pre><code>

    	$m_event = new EventModel();
    	$m_act = new ActModel();
    	$events = $m_event-&gt;cache-&gt;fetchAll(array("status='1'","deleted='0'"),'createdate desc',10,0);
    	echo "&lt;ul&gt;";
    	foreach($events as $event){
    		echo "&lt;li&gt;".$event-&gt;event_id."&lt;/li&gt;";
			$event-&gt;prep($m_event);

    		$acts = $event-&gt;cache-&gt;findDependentRowset('ActModel');
    		echo "&lt;ul&gt;";
    		foreach($acts as $act){
    			$act-&gt;prep($m_act);
    			$foo = $act-&gt;cache-&gt;findParentRow('EventModel');
    			echo "&lt;li&gt;".$act-&gt;act_id." (".$foo-&gt;event_id.")&lt;/li&gt;";
    		}
    		echo "&lt;/ul&gt;";
    	}
    	echo "&lt;/ul&gt;";

</code></pre>
<p>Easy, isn&#8217;t it ? The caching is flexible, so it doesn&#8217;t matter if all rows are in the cache. All combinations are working. To bypass the cache you can use the model directly without the -&gt;cache-&gt;.</p>
<p>The cache class is using Zend_Config for some parameters, for reference here are the values:</p>
<pre>caching.cache_by_default	= true
caching.default_cache_id_prefix	= default_
caching.lifetime			= 300
caching.backendName			= Memcached</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
