<?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>Joey Rivera &#187; zend_cache</title>
	<atom:link href="http://www.joeyrivera.com/tag/zend_cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.joeyrivera.com</link>
	<description>Blogging about PHP, Actionscript, MySQL, and other interests.</description>
	<lastBuildDate>Wed, 04 Aug 2010 14:52:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using Zend_Paginator with Twitter API and Zend_Cache</title>
		<link>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/</link>
		<comments>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 19:15:08 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[twitter api]]></category>
		<category><![CDATA[twitter services]]></category>
		<category><![CDATA[zend_cache]]></category>
		<category><![CDATA[zend_paginator]]></category>
		<category><![CDATA[zend_rest_client]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=545</guid>
		<description><![CDATA[Zend Framework 1.10.0 is out and a comment was posted on my blog that lead me to creating this new post. I&#8217;m going to focus more on Zend_Paginator and Zend_Rest_Client to access Twitters API since I&#8217;ve already created a post on Zend_Cache. Normally, I would use Zend_Service_Twitter to access the twitter service but it still [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework 1.10.0 is out and a comment was posted on my blog that lead me to creating this new post. I&#8217;m going to focus more on Zend_Paginator and Zend_Rest_Client to access Twitters API since I&#8217;ve already created a post on <a title="Caching using Zend_Cache" href="http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/">Zend_Cache</a>. Normally, I would use <a title="Zend Framework Zend_Service_Twitter" href="http://framework.zend.com/manual/en/zend.service.twitter.html">Zend_Service_Twitter</a> to access the twitter service but it still seems to require authentication to retrieve a users timeline where <a title="Twitter API" href="http://apiwiki.twitter.com/Twitter-REST-API-Method:-statuses-user_timeline?SearchFor=statuses&amp;sp=2">only protected users</a> should require authentication.</p>
<h4>Zend_Paginator</h4>
<p>Zend_Paginator from the Zend Framework site:</p>
<blockquote><p>Zend_Paginator is a flexible component for paginating collections of data and presenting that data to users.</p></blockquote>
<p>Zend_Paginator automatically creates pagination for you by setting up a few parameters and passing it an array of data. What is pagination, if you have ever gone to <a title="Google Search Joey Rivera" href="http://www.google.com/search?rlz=1C1GGLS_enUS291US304&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=joey+rivera">Google</a> and searched for anything, usually you&#8217;ll see something like the following at the bottom of the search results page:</p>
<p style="text-align: center;"><img class="alignnone" title="Google Pagination Example" src="http://farm3.static.flickr.com/2759/4310975845_292c7ffca0_o.gif" alt="" width="267" height="61" /></p>
<p>See the numbers and the text links, this is called pagination. So much data exists for the particular search that it wouldn&#8217;t make sense to display it all in one page. It would cause large amounts of scrolling down to view, the load time of the page would be affected, so we rather show fewer results and give our users the option of viewing more by clicking on the pagination links.</p>
<p>To demonstrate how to use Zend_Paginator I created a sample Zend Framework 1.10.0 application. This application grabs my last 50 tweets using the Twitter API and displays them 10 at a time using Zend_Paginator. I use Zend_Cache to cache my twitter data so I don&#8217;t have to spend time accessing their api every time &#8211; I&#8217;m sure they would appreciate it.</p>
<h4>Bootstrap</h4>
<p>The first step was to create a new zend framework project. I&#8217;m making the assumption that if you are reading this then you already know how to do this. After creating my new project, I added two methods to my bootstrap file to autoload and to init Zend_Cache. My bootstrap looks like the following:<br />
<span id="more-545"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">class</span> Bootstrap <span class="kw2">extends</span> Zend_Application_Bootstrap_Bootstrap<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> _initAutoload<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$autoloader</span> = <span class="kw2">new</span> Zend_Application_Module_Autoloader<span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;namespace&#8217;</span> =&gt; <span class="st0">&#8216;My&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;basePath&#8217;</span> &nbsp;=&gt; APPLICATION_PATH,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="kw2">function</span> _initCache<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$front</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="nu0">10</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$back</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; APPLICATION_PATH . <span class="st0">&#8216;/../cache&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Core&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$front</span>, <span class="re0">$back</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Zend_Registry::<span class="me2">set</span><span class="br0">&#40;</span><span class="st0">&#8216;cache&#8217;</span>, <span class="re0">$cache</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>For caching to work correctly, I had to create the &#8216;cache&#8217; folder in my site root. Notice I set a cache lifetime in my bootstrap, I&#8217;ll be overriding it later for my twitter service. I like to set a general lifetime when caching and override the items that I believe need a different lifetime value.</p>
<h4>Twitter Service</h4>
<p>Next was creating my twitter service. I added a folder &#8217;service&#8217; under &#8216;application&#8217; and created a file called &#8216;Twitter.php&#8217;. Here is the content for that file:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">class</span> My_Service_Twitter<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; const CACHELIFETIME = <span class="nu0">3600</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="re0">$_screen_name</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="re0">$_cache</span> = <span class="kw2">null</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="re0">$screen_name</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_screen_name = <span class="re0">$screen_name</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_cache = Zend_Registry::<span class="me2">get</span><span class="br0">&#40;</span><span class="st0">&#8216;cache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> getUserTimeline<span class="br0">&#40;</span><span class="re0">$count</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache_id</span> = <span class="st0">&#8216;twitter_&#8217;</span> . <span class="re0">$this</span>-&gt;_screen_name . <span class="re0">$count</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="re0">$data</span> = <span class="re0">$this</span>-&gt;_cache-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span> = <span class="kw2">new</span> Zend_Rest_Client<span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/user_timeline.xml&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// setup params for service call</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span>-&gt;<span class="me1">screen_name</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_screen_name<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$client</span>-&gt;<span class="me1">count</span><span class="br0">&#40;</span><span class="re0">$count</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// call service and get all data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$raw_data</span> = <span class="re0">$client</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// create array with the data we want &#8211; text is the actual tweet 140 chars</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$raw_data</span>-&gt;<span class="me1">error</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$raw_data</span>-&gt;<span class="me1">status</span> <span class="kw1">as</span> <span class="re0">$tweet</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;text&#8217;</span><span class="br0">&#93;</span> = <span class="br0">&#40;</span>string<span class="br0">&#41;</span><span class="re0">$tweet</span>-&gt;<span class="me1">text</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// save array to cache &#8211; override cache lifetime</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_cache-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$cache_id</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;twitter&#8217;</span><span class="br0">&#41;</span>, self::<span class="me2">CACHELIFETIME</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>Let me explain what I&#8217;m doing here. First I setup some variables. I setup the cache lifetime var to an hour since I don&#8217;t want to be hitting twitter to often and I don&#8217;t tweet more than a couple times a day anyways. In the construct, I simply set my class properties. Twitter API has various service calls you can make. For the purpose of this app, I simply want to return the last 50 tweets posted by a public user &#8211; me. If you look at the twitter docs, you&#8217;ll see <a title="Twitter Statuses User Timeline Method" href="http://apiwiki.twitter.com/Twitter-REST-API-Method:-statuses-user_timeline?SearchFor=statuses&amp;sp=2">statuses user_timeline</a> will give us just that. The call to the service is very simple. We create a Zend_Rest_Client instance to the service url: http://twitter.com/statuses/user_timeline.xml. Then we setup both parameters (check the link to the twitter api to see the rest of the available params) screen name (the twitter account you are looking for) and count (how many tweets to get back) and call $client-&gt;get(). When I get the raw data from twitter, I create an array storing only the data I need which is text (the actual content of your tweets 140 characters).</p>
<p>Easy enough? I thought so. You&#8217;ll also notice that this functionality is wrapped with caching code. Before calling the service, I check to see if this information is already cached and valid. If so, I just return the cached array else I call the service and store the array in cache. More info my <a title="Caching using PHP/Zend_Cache and MySQL" href="http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/">Zend_Cache</a> post on how Zend_Cache works.</p>
<h4>IndexController</h4>
<p>Next I added the following call to my IndexController:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">public</span> <span class="kw2">function</span> indexAction<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// needed vars</span><br />
&nbsp; &nbsp; <span class="re0">$screen_name</span> = <span class="st0">&#8216;joeyrivera&#8217;</span>;<br />
&nbsp; &nbsp; <span class="re0">$total_tweets</span> = <span class="nu0">50</span>;<br />
&nbsp; &nbsp; <span class="re0">$tweets_per_page</span> = &nbsp;<span class="nu0">10</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// get tweets</span><br />
&nbsp; &nbsp; <span class="re0">$service</span> = <span class="kw2">new</span> My_Service_Twitter<span class="br0">&#40;</span><span class="re0">$screen_name</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$service</span>-&gt;<span class="me1">getUserTimeline</span><span class="br0">&#40;</span><span class="re0">$total_tweets</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// init paginator</span><br />
&nbsp; &nbsp; <span class="re0">$paginator</span> = Zend_Paginator::<span class="me2">factory</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$paginator</span>-&gt;<span class="me1">setItemCountPerPage</span><span class="br0">&#40;</span><span class="re0">$tweets_per_page</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;<span class="me1">setCurrentPageNumber</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;_getParam<span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// send paginator to view</span><br />
&nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">paginator</span> = <span class="re0">$paginator</span>;<br />
<span class="br0">&#125;</span></div>
<p>I started by setting up required params. Then initializing My_Service_Twitter and calling the getUserTimeline method.$data gets all 50 tweets from Twitter through Zend_Rest_Client or loaded straight from the cache. Last few steps are calling Zend_Paginator::factory and passing in the $data array of tweets. The next line sets the number of items we want displayed per page and sets the current page number &#8211; the page querystring variable (<a title="Zend_Paginator Config" href="http://framework.zend.com/manual/en/zend.paginator.configuration.html">more options here</a>). This last part will make sense soon when I show you the pagination.phtml (the actual pagination controls) file that renders the page numbers and previous/next links in the view. Since we are done with our paginator var, we pass it to our view to display.</p>
<h4>Index View</h4>
<p>The view is pretty simple, all it does is display the list of tweets, 10 tweets per page. It also needs to display the pagination controls which is the file I mentioned earlier. Here is the index.phtml file:</p>
<div class="dean_ch" style="white-space: wrap;">&lt; ?php <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span><span class="br0">&#41;</span><span class="br0">&#41;</span>: <span class="kw2">?&gt;</span><br />
&lt;ul&gt;<br />
&lt; ?php <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span> <span class="kw1">as</span> <span class="re0">$item</span><span class="br0">&#41;</span>: <span class="kw2">?&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;&lt; ?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$item</span><span class="br0">&#91;</span><span class="st0">&#8216;text&#8217;</span><span class="br0">&#93;</span>; ?&gt;&lt;/li&gt;<br />
&lt; ?php <span class="kw1">endforeach</span>; ?&gt;&lt;/ul&gt;<br />
&lt; ?php <span class="kw1">endif</span>; <span class="kw2">?&gt;</span></p>
<p>&lt; ?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$this</span>-&gt;<span class="me1">paginationControl</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">paginator</span>, <span class="st0">&#8216;Sliding&#8217;</span>, <span class="st0">&#8216;pagination.phtml&#8217;</span><span class="br0">&#41;</span>; <span class="kw2">?&gt;</span></div>
<p>If any items are found, the loop takes place and the items are displayed in the list. Zend_Paginator takes care of handling how many items to show and for what page using that parameters we setup earlier. The last line is important. There are different styles you can use when displaying your pagination such as &#8217;sliding&#8217;, &#8216;jumping&#8217;, &#8216;elastic&#8217; and more. You can read about them all in the <a href="http://framework.zend.com/manual/en/zend.paginator.usage.html">zend docs</a>. &#8216;pagination.phtml&#8217; is the file used to display the page numbers and next/previous links. This file can be made so it&#8217;s reusable across your application and you can customize it anyway you like.</p>
<h4>Pagination.phtml</h4>
<p>Here is my file which is located in my views/scripts/ folder:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">pageCount</span> == <span class="nu0">1</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// previous</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">previous</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$this</span>-&gt;<span class="me1">previous</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;&lt; Previous&lt;/a&gt; &#8216;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt; Previous &#8216;</span>; <span class="br0">&#125;</span> <span class="co1">// pages foreach($this-&gt;pagesInRange as $page)</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$page</span> != <span class="re0">$this</span>-&gt;<span class="me1">current</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$page</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;&#8217;</span>.<span class="re0">$page</span>.<span class="st0">&#8216;&lt;/a&gt; &#8216;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &#8216;</span>, <span class="re0">$page</span>, <span class="st0">&#8216; &#8216;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// next</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">next</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; &lt;a href=&quot;&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;page&#8217;</span> =&gt; <span class="re0">$this</span>-&gt;<span class="me1">next</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&#8216;&quot;&gt;Next &gt;&lt;/a&gt;&#8217;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216; Next &gt;&#8217;</span>;<br />
<span class="br0">&#125;</span></div>
<p>If there is only 1 page, do nothing else display the page numbers and if there is a previous or next page, display those links as well. Notice I&#8217;m setting a page variable to add to my querystring. This is so Zend_Paginator knows what page I&#8217;m currently at and can display the correct items. For example: &#8216;www.myapp.com/index/index/&#8217; would default to page one. &#8216;www.myapp.com/index/index/page/3&#8242; would let paginator know we want to display the items that belong to page 3. It also lets the pagination.phtml file know if there is a page 2 and/or 4 to display a back and previous link.</p>
<p style="text-align: left;">Here is a image of the end result:<br />
<img class="aligncenter" src="http://farm5.static.flickr.com/4051/4311491187_79fd88ec56_o.gif" alt="" width="549" height="168" /></p>
<h4>Final Thoughts</h4>
<p>That&#8217;s pretty much it. Hopefully I&#8217;m not forgetting anything. Notice I don&#8217;t have any filtering/validating anywhere. I just wrote this quickly to give a basic understanding on how to use these modules together. I think I&#8217;m going to update my &#8216;Interesting Images&#8217; and &#8216;Interesting Links&#8217; widgets on my sidebar to use pagination and allow users to view older entries.</p>
<p>Something to keep in mind for optimization purposes. Depending on where you are getting your data and how much data you want, it makes more sense to get a total number of items to get an idea of how many pages you need (not get all the data at once!). Then for each page you can get the data that needs to be displayed. For example, I would never call twitter and say: bring back my last one thousand tweets just so I can display 10 on a page and one hundred page numbers. That would be an extreme waste of resources. Instead, I could ask Twitter: how many tweets do I have in total which is all I need to draw my pagination. Then for each page, I can download the data I need and display.</p>
<p>Feel free to leave any questions or comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Caching using PHP/Zend_Cache and MySQL</title>
		<link>http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/</link>
		<comments>http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 19:25:06 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_cache]]></category>
		<category><![CDATA[zend_cache_backend_file]]></category>
		<category><![CDATA[zend_cache_frontend_core]]></category>
		<category><![CDATA[zend_cache_frontend_page]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=443</guid>
		<description><![CDATA[I like the definition used in Wikipedia: &#8220;a cache is a temporary storage area where often accessed data can be stored for quick access&#8221;. The idea is to get &#8216;often accessed data&#8217; from a database and store it in memory (RAM or as a file in your local file system). This is because:

it&#8217;s quicker for a [...]]]></description>
			<content:encoded><![CDATA[<p>I like the definition used in <a href="http://simple.wikipedia.org/wiki/Cache">Wikipedia</a>: &#8220;a cache is a temporary storage area where often accessed data can be stored for quick access&#8221;. The idea is to get &#8216;often accessed data&#8217; from a database and store it in memory (RAM or as a file in your local file system). This is because:</p>
<ul>
<li>it&#8217;s quicker for a machine to read from memory than to connect to a database and query data.</li>
<li>it&#8217;s more efficient for the database to not waste time and resources returning the same dataset multiple times when it could be focusing on other tasks.</li>
</ul>
<p>As long as the data, in this scenario from the database, doesn&#8217;t change, there is no need to query it again.</p>
<p>Resources are limited on systems and to take advantage of your resources, you need to make sure time isn&#8217;t spent on tasks that could be handled better elsewhere. Here is a silly real world example. Imagine on a daily basis, I have to track how many magazines I have and send this information to Person X. I get new magazines at the beginning of each month only. To track the number of magazines I have every day I could</p>
<ol type="A">
<li>Count them, one by one every day and send Person X the total. If I have 50 magazines this could take some time and assume I get 10 more every month, after a year or two I could spend all day just counting how many magazines I have instead of working. Sound productive?</li>
<li>Count them once and write the number down on a piece of paper (caching!). Everyday when Person X asks how many magazines I have, I read the number from the piece of paper. Only when I get new magazines (once a month) do I count them again (or just add the current number + the new amount) to get my new total. Then I update my piece of paper with the new total (updating the value in cache).</li>
</ol>
<p>The latter is definitely the more productive choice.</p>
<p>The same idea applies to computer systems. In the web, you have static and dynamic files. Static files are quicker to serve on a server because the server only has to read the contents of the file and send it to the browser requesting it. Dynamic pages take more time and resources because the server needs to execute the code in the page and only once it&#8217;s done can it send the request back. PHP can be used to create dynamic pages. The server executes the php code and spits out a file that then is read by the browser. If a database is involved, then the database has to run it&#8217;s task as well before the final file is returned.</p>
<p>When ever possible, it&#8217;s more efficient to serve a static file or static content. We use cache to accomplish this. In this post I&#8217;m going to talk about caching files and database queries to local files on the server.<span id="more-443"></span></p>
<h4>Zend_Cache</h4>
<p>There are different ways to achieve this. I personally use <a href="http://framework.zend.com/manual/en/">Zend Framework</a> on my projects so I&#8217;ll be using <a href="http://framework.zend.com/manual/en/zend.cache.html">Zend_Cache</a> in my examples. I will only be using Zend_Cache as a standalone module, not the entire framework. This way, those of you who don&#8217;t use Zend Framework can still follow this guide. There are other options if you don&#8217;t have Zend such as <a href="http://pear.php.net/manual/en/package.caching.cache-lite.intro.php">Cache_Lite</a> which is part of the <a href="http://pear.php.net/">PEAR Framework</a>. Both work very similarly.</p>
<p>Zend_Cache is very flexible in that it lets you decide what you want to cache (the frontend) and where you want to put it (the backend). The different frontends for Zend_Cache include (taken from the <a href="http://framework.zend.com/manual/en/zend.cache.frontends.html#zend.cache.frontends.core">Zend docs</a>):</p>
<ul>
<li><strong>Zend_Cache_Core</strong> is a special frontend because it is the core of the module. It is a generic cache frontend and is extended by other classes.</li>
<li><strong>Zend_Cache_Frontend_Output</strong> is an output-capturing frontend. It utilizes output buffering in PHP to capture everything between its start() and end() methods.</li>
<li><strong>Zend_Cache_Frontend_Function</strong> caches the results of function calls. It has a single main method named call() which takes a function name and parameters for the call in an array.</li>
<li><strong>Zend_Cache_Frontend_Class</strong> is different from Zend_Cache_Frontend_Function because it allows caching of object and static method calls.</li>
<li><strong>Zend_Cache_Frontend_File</strong> is a frontend driven by the modification time of a &#8220;master file&#8221;. It&#8217;s really interesting for examples in configuration or templates issues. It&#8217;s also possible to use multiple master files.</li>
<li><strong>Zend_Cache_Frontend_Page</strong> is like Zend_Cache_Frontend_Output but designed for a complete page. It&#8217;s impossible to useZend_Cache_Frontend_Page&lt; for caching only a single block.</li>
</ul>
<p>The backends include:</p>
<ul>
<li><strong>Zend_Cache_Backend_File</strong> &#8211; This (extended) backends stores cache records into files (in a choosen directory).</li>
<li><strong>Zend_Cache_Backend_Sqlite</strong> &#8211; This (extended) backends stores cache records into a SQLite database.</li>
<li><strong>Zend_Cache_Backend_Memcached</strong> &#8211; This (extended) backends stores cache records into a memcached server. memcached is a high-performance, distributed memory object caching system. To use this backend, you need a memcached daemon and the memcache PECL extension.</li>
<li><strong>Zend_Cache_Backend_Apc</strong> &#8211; This (extended) backends stores cache records in shared memory through the APC (Alternative PHP Cache) extension (which is of course need for using this backend).</li>
<li><strong>Zend_Cache_Backend_Xcache</strong> &#8211; This backends stores cache records in shared memory through the XCache extension (which is of course need for using this backend).</li>
<li>and a couple more you can check in the Zend docs.</li>
</ul>
<p>For my first example I&#8217;ll be using the &#8216;Core&#8217; frontend (to cache a variable) and the &#8216;File&#8217; backend (to save that variable to a file on the server). I will actually be using the &#8216;File&#8217; backend on all my examples since I have not had the opportunity to work with and of the other backend methods. Reading from RAM is quicker than reading from the file system so using other backend methods which take advantage of this would yield better results.</p>
<h4>Setting up the Environment</h4>
<p>Before I go into the first example, let me explain how I set up my environment. Like i mentioned earlier, I won&#8217;t be using the Zend Framework, instead I will only be using Zend_Cache as a standalone module. To accomplish this, I create a library folder in my site root. Then I create a Zend folder inside of library where I will be putting the Cache module in. The next step requires that you download the <a href="http://framework.zend.com/download/current/">Zend Framework zip file</a> so you can copy the cache module found in the zip (minimal package is all you need). Once you download the file, open it and copy Cache.php from /library/Zend/Cache.php and the /library/Zend/Cache folder to your Zend folder in library. Here is an image of what your structure should look like:</p>
<div class="wp-caption aligncenter" style="width: 190px"><img title="Folder Structure" src="http://farm3.static.flickr.com/2802/4078156497_c2b13c294d_m.jpg" alt="Folder Structure" width="180" height="125" /><p class="wp-caption-text">Folder Structure</p></div>
<h4>Example 1 &#8211; Caching a Variable</h4>
<p>The first example is a slightly modified version of the example given on the Zend_Cache docs:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">include</span> <span class="st0">&#8216;library/Zend/Cache.php&#8217;</span>;</p>
<p><span class="re0">$frontendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp;<span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="nu0">10</span>,<br />
&nbsp; &nbsp;<span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$backendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; <span class="st0">&#8216;tmp/&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Core&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$frontendOptions</span>, <span class="re0">$backendOptions</span><span class="br0">&#41;</span>;<br />
<span class="re0">$id</span> = <span class="st0">&#8216;myBigLoop&#8217;</span>;</p>
<p><span class="re0">$start_time</span> = <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">if</span><span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="re0">$data</span> = <span class="re0">$cache</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Not found in Cache&lt;br /&gt;&quot;</span>;</p>
<p>&nbsp; &nbsp; <span class="re0">$data</span> = <span class="st0">&#8221;</span>;<br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>; <span class="re0">$i</span> &lt; <span class="nu0">1000000</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$data</span> . <span class="re0">$i</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="re0">$cache</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Running from Cache&lt;br /&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;%01.4f&#8217;</span>, <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> &#8211; <span class="re0">$start_time</span><span class="br0">&#41;</span>;</div>
<p>What&#8217;s going on? First I include Zend_Cache. Next I declare two arrays with configuration values needed to use Zend_Cache. The frontendOptions array is setting a cache lifetime of 10 seconds. Meaning, after a cache file is created, it will only live for 10 seconds. After that, the cache file will be recreated. In the backendOptions array, I set the folder where I want my cache files to be saved to. I&#8217;m using a folder called &#8216;tmp&#8217; that I created in the root of my site. Make sure to create that folder or your code may not work.</p>
<p>Next I create my $cache variable telling Zend_Cache that I want to use &#8216;Core&#8217; as the frontend and &#8216;File&#8217; as the backend. $id is just any name you want to give to this particular cached value. If you wanted to cache two different variables, you would want to use two different id&#8217;s for each to not overwrite one-another. $start_time is going to track when my code started running so I can check how long it took to execute my loop at the end.</p>
<p>This is where it gets fun yet so simple. The if statement checks the following</p>
<ul>
<li>$cache-&gt;load($id) will check to see if a valid cache file exists for that $id and return it.</li>
<li>$data is set to the return of $cache-&gt;load (whether there is or isn&#8217;t anything there)</li>
<li>Finally the if checks to see if there is NO data in $data and if so, processes the loop else echos &#8216;Running from Cache&#8217;</li>
</ul>
<p>If the if statement determines there is NO data in cache, it will continue with the code to do a loop. The for statement will loop 1,000,000 &#8211; one million times, and append each number to the variable $data. After it is done running a million times, it saves the variable $data into cache using the $id declared in the $cache-&gt;load() call. When it&#8217;s done the code spits out the time it took to execute this code. In my server it&#8217;s usually around 0.4 seconds:</p>
<div class="wp-caption aligncenter" style="width: 143px"><img title="Without Cache" src="http://farm3.static.flickr.com/2662/4078911942_d75a502d73_m.jpg" alt="Without Cache" width="133" height="45" /><p class="wp-caption-text">in seconds</p></div>
<p>Now if it run my code again, hitting refresh, the code will go to the if() and find there is a cache file for that $id and load it &#8211; so it will not run the for loop. In this scenario, the page usually only takes about .02 to .03 seconds to execute:</p>
<div class="wp-caption aligncenter" style="width: 143px"><img title="Using Cache" src="http://farm3.static.flickr.com/2563/4078156469_be20770d09_m.jpg" alt="Using Cache" width="133" height="45" /><p class="wp-caption-text">in seconds</p></div>
<p>That&#8217;s a nice improvement. For the next 10 seconds (while the cache file is valid since we set its lifetime to 10 seconds) the page will only take 0.03 seconds to run instead of 0.4 seconds. That&#8217;s over 15 times (94%) faster! &#8220;Rudimentary, this is a difference of serving 149 requests per minute versus 2307 requests per minute.&#8221; You can always look inside your tmp folder and see if files are being created there to make sure things are really working. If you delete them, next time you execute the page it should recreate the cache files.</p>
<h4>Example 2 &#8211; Caching a Database RecordSet</h4>
<p>This example will be extremely similar to the previous one. In both, we are setting a variable to hold a value, then we save that variable in cache. Each time we run the page we check for the cache file, if it exists we use it, else we query the database, get the recordset, and store it in cache.</p>
<h4>Setting up the Database</h4>
<p>In this example we will be using the same table &#8216;users&#8217; that I used in some of my previous posts. Below is the create statement to create the table &#8216;users&#8217; in the database &#8216;test&#8217;:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">DROP TABLE</span> IF <span class="kw1">EXISTS</span> `test`.`users`;<br />
<span class="kw1">CREATE TABLE</span> &nbsp;`test`.`users` <span class="br0">&#40;</span><br />
&nbsp; `users_id` <span class="kw2">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span> <span class="kw3">AUTO_INCREMENT</span>,<br />
&nbsp; `first_name` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; `last_name` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw3">NOT NULL</span>,<br />
&nbsp; <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span>`users_id`<span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=<span class="kw1">INNODB</span> <span class="kw3">DEFAULT</span> <span class="kw3">CHARSET</span>=latin1;</div>
<p>Once you create the table insert the following data:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> users<br />
<span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="kw3">NULL</span>, <span class="st0">&#8216;Joey&#8217;</span>, <span class="st0">&#8216;Rivera&#8217;</span><span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="kw3">NULL</span>, <span class="st0">&#8216;John&#8217;</span>, <span class="st0">&#8216;Doe&#8217;</span><span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="kw3">NULL</span>, <span class="st0">&#8216;Joey&#8217;</span>, <span class="st0">&#8216;Tester&#8217;</span><span class="br0">&#41;</span>,<br />
<span class="br0">&#40;</span><span class="kw3">NULL</span>, <span class="st0">&#8216;Joey&#8217;</span>, <span class="st0">&#8216;Test&#8217;</span><span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="kw3">NULL</span>, <span class="st0">&#8216;Billy&#8217;</span>, <span class="st0">&#8216;Bob&#8217;</span><span class="br0">&#41;</span>;</div>
<p>Ok, now the code. The objective will be to grab all the information for all the users in the table from the database. Once we have it, store it in cache until that table is updated and we need to query it again. We are going to use a null value for lifetime so that the cache file never expires and we are then going to manually &#8211; in code, delete the cache file when we know the table has been changed.</p>
<p>This is what the code looks like:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">include</span> <span class="st0">&#8216;library/Zend/Cache.php&#8217;</span>;</p>
<p><span class="re0">$frontendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp;<span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="kw2">null</span>,<br />
&nbsp; &nbsp;<span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$backendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; <span class="st0">&#8216;tmp/&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Core&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$frontendOptions</span>, <span class="re0">$backendOptions</span><span class="br0">&#41;</span>;<br />
<span class="re0">$id</span> = <span class="st0">&#8216;rs&#8217;</span>;</p>
<p><span class="re0">$start_time</span> = <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">if</span><span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="re0">$data</span> = <span class="re0">$cache</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Not found in Cache&lt;br /&gt;&quot;</span>;</p>
<p>&nbsp; &nbsp; <a href="http://www.php.net/mysql_connect"><span class="kw3">mysql_connect</span></a><span class="br0">&#40;</span><span class="st0">&#8216;localhost&#8217;</span>, <span class="st0">&#8216;user&#8217;</span>, <span class="st0">&#8216;password&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://www.php.net/mysql_select_db"><span class="kw3">mysql_select_db</span></a><span class="br0">&#40;</span><span class="st0">&#8216;test&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$query</span> = <span class="st0">&#8217;select * from users&#8217;</span>;<br />
&nbsp; &nbsp; <span class="re0">$rs</span> = <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="re0">$data</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$row</span> = <a href="http://www.php.net/mysql_fetch_assoc"><span class="kw3">mysql_fetch_assoc</span></a><span class="br0">&#40;</span><span class="re0">$rs</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$row</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="re0">$cache</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Running from Cache&lt;br /&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="co1">//echo &#8216;&lt;pre&gt;&#8217;;</span><br />
<span class="co1">//print_r($data);</span><br />
<span class="co1">//echo &#8216;&lt;/pre&gt;&#8217;;</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;%01.4f&#8217;</span>, <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> &#8211; <span class="re0">$start_time</span><span class="br0">&#41;</span>;</div>
<p>This code is very similar to the first example. The differences are I changed the frontendOptions lifetime value from 10 seconds to null &#8211; so the cache file never expires. Then I changed the $id value to &#8216;rs&#8217; so it doesn&#8217;t overwrite the example one cache file. Now instead of looping in the if statement, I connect to the database, query the users table, and create an array of all the rows returns. Then I save it in cache and echo out the time it took to execute. The next time, the code will find the cache file for this $id and go to the else statement and then echo the time.</p>
<p>Time taken without cache (querying database):</p>
<div class="wp-caption aligncenter" style="width: 143px"><img title="Without Cache" src="http://farm3.static.flickr.com/2635/4079111872_f5d4c607db_m.jpg" alt="in seconds" width="133" height="45" /><p class="wp-caption-text">in seconds</p></div>
<p>Time taken with cache (not querying the database):</p>
<div class="wp-caption aligncenter" style="width: 143px"><img title="With Cache" src="http://farm3.static.flickr.com/2650/4079111856_fc14ce7f52_m.jpg" alt="in seconds" width="133" height="45" /><p class="wp-caption-text">in seconds</p></div>
<p>As you can see, big improvement again &#8211; 33 times (97%) faster. &#8220;This is a difference of serving 4,477 requests per minute versus 150,000 requests per minute!&#8221; Feel free to uncomment the echo/print_r to see the data from the array. You can then update one of the users name in the database and run this page again. Notice you don&#8217;t see the new change. This is because we told the cache file to never expire so no matter what changes you make to your users in the users table, this page will continue to load the data from the cache file.</p>
<h4>Clearing the Cache File</h4>
<p>Depending on your needs, you may want the cache file to expire every 5 minutes, 2 hours, each day, or never. Even if you set a time interval for the cache file to expire, you may at some point find yourself needing to clear the cache early so this will show you how.</p>
<p>Clearing the cache is as simple as calling $cache-&gt;remove($id).  We need to add some code to delete a cache file when the users table is updated.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">include</span> <span class="st0">&#8216;library/Zend/Cache.php&#8217;</span>;</p>
<p><span class="re0">$frontendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp;<span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="kw2">null</span>,<br />
&nbsp; &nbsp;<span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$backendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; <span class="st0">&#8216;tmp/&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Core&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$frontendOptions</span>, <span class="re0">$backendOptions</span><span class="br0">&#41;</span>;<br />
<span class="re0">$id</span> = <span class="st0">&#8216;rs&#8217;</span>;</p>
<p><span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#8216;form_submit&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &amp;&amp; <span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#8216;form_submit&#8217;</span><span class="br0">&#93;</span> == <span class="st0">&#8216;clear&#8217;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache</span>-&gt;<span class="me1">remove</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="re0">$start_time</span> = <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">if</span><span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="re0">$data</span> = <span class="re0">$cache</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Not found in Cache&lt;br /&gt;&quot;</span>;</p>
<p>&nbsp; &nbsp; <a href="http://www.php.net/mysql_connect"><span class="kw3">mysql_connect</span></a><span class="br0">&#40;</span><span class="st0">&#8216;localhost&#8217;</span>, <span class="st0">&#8216;user&#8217;</span>, <span class="st0">&#8216;password&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://www.php.net/mysql_select_db"><span class="kw3">mysql_select_db</span></a><span class="br0">&#40;</span><span class="st0">&#8216;test&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$query</span> = <span class="st0">&#8217;select * from users&#8217;</span>;<br />
&nbsp; &nbsp; <span class="re0">$rs</span> = <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="re0">$data</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$row</span> = <a href="http://www.php.net/mysql_fetch_assoc"><span class="kw3">mysql_fetch_assoc</span></a><span class="br0">&#40;</span><span class="re0">$rs</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$row</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="re0">$cache</span>-&gt;<span class="me1">save</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Running from Cache&lt;br /&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;%01.4f&#8217;</span>, <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> &#8211; <span class="re0">$start_time</span><span class="br0">&#41;</span>;<br />
<span class="kw2">?&gt;</span><br />
&lt;form method=<span class="st0">&quot;get&quot;</span>&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input name=<span class="st0">&quot;form_submit&quot;</span> type=<span class="st0">&quot;submit&quot;</span> value=<span class="st0">&quot;reload&quot;</span>&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;input name=<span class="st0">&quot;form_submit&quot;</span> type=<span class="st0">&quot;submit&quot;</span> value=<span class="st0">&quot;clear&quot;</span>&gt;<br />
&lt;/form&gt;</div>
<p>The only difference between this code and the one above is I added a form at the end of the page. This form has two buttons, one we will use to reload the page without clearing the cache and the other button we will use to clear the cache after the page is submitted. If you look at the php code, you&#8217;ll notice a new if statement.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">if</span><span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#8216;form_submit&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &amp;&amp; <span class="re0">$_GET</span><span class="br0">&#91;</span><span class="st0">&#8216;form_submit&#8217;</span><span class="br0">&#93;</span> == <span class="st0">&#8216;clear&#8217;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cache</span>-&gt;<span class="me1">remove</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
<p>This code checks to see if you selected the &#8216;clear&#8217; button. If so, it calls the remove method in $cache to clear the cached file for $id. Right above this we are still initializing $cache the same way we use it when we want to cache a variable and we are still using the same $id &#8216;rs&#8217;.</p>
<h4>Example 3 &#8211; Caching a Page</h4>
<p>This is probably the easiest of them all because you don&#8217;t need to specify an id. The page is cached based on the url as the id. All you need to do it call $cache-start() after initializing the cache variable using &#8216;Page&#8217; as the frontend. Everything else happens behind the scene. You don&#8217;t even have to call the save() method since anything outputted by the page will be cached. Here is the code, modified from example 1:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">include</span> <span class="st0">&#8216;library/Zend/Cache.php&#8217;</span>;</p>
<p><span class="re0">$frontendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp;<span class="st0">&#8216;lifetime&#8217;</span> =&gt; <span class="nu0">10</span>,<br />
&nbsp; &nbsp;<span class="st0">&#8216;automatic_serialization&#8217;</span> =&gt; <span class="kw2">true</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$backendOptions</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;cache_dir&#8217;</span> =&gt; <span class="st0">&#8216;tmp/&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$cache</span> = Zend_Cache::<span class="me2">factory</span><span class="br0">&#40;</span><span class="st0">&#8216;Page&#8217;</span>, <span class="st0">&#8216;File&#8217;</span>, <span class="re0">$frontendOptions</span>, <span class="re0">$backendOptions</span><span class="br0">&#41;</span>;<br />
<span class="re0">$cache</span>-&gt;<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$start_time</span> = <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;Not found in Cache&lt;br /&gt;&quot;</span>;</p>
<p><span class="re0">$data</span> = <span class="st0">&#8221;</span>;<br />
<span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>; <span class="re0">$i</span> &lt; <span class="nu0">1000000</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$data</span> . <span class="re0">$i</span>;<br />
<span class="br0">&#125;</span></p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;%01.4f&#8217;</span>, <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> &#8211; <span class="re0">$start_time</span><span class="br0">&#41;</span>;</div>
<p>The few differences here are using &#8216;Page&#8217; as the frontend instead of &#8216;Core&#8217;. Notice that I removed the if statement since we don&#8217;t have to check for a cache file, simply calling $cache-start() will do that for us. And finally I don&#8217;t save a variable to save since as mentioned above, $cache-start() takes care of this as well.</p>
<p>There should be a slight delay loading this page the first time since it&#8217;s not cached yet. If you reload the page multiple times, you&#8217;ll notice the value in the timer doesn&#8217;t change even though the page loads much quicker. This is because all the output sent to the browser is cached, including the timer. So in this scenario, the timer is pretty useless since the value will be correct only when the code runs outside of the cache every 10 seconds (the lifetime is set to 10 seconds instead of null for this example). Every 10 seconds of reloading this page, you should see the timer change value.</p>
<h4>Additional Thoughts</h4>
<p>Cache is a powerful tool. You can save resources and time which could also mean saving money (with very little extra code!). You can have a very dynamic site which requires lots of processing and heavily relies on a database queries, creating bottlenecks that could be easily alleviated by caching instead of buying a lot more expensive hardware.</p>
<p>There is a slight overhead in using cache though. This is because your system has to read and write to files where before it wouldn&#8217;t have had to. So make sure you are using cache in a way that makes sense. Don&#8217;t use it for the fun of using it, make sure you use it to solve a problem or make a process more efficient.</p>
<p>As seen from these three examples, there are many ways to cache, so you can be creative. Sometimes caching an array makes sense, sometimes caching a whole page doesn&#8217;t. You just need to think about what the need is and how to best address it.</p>
<p>Also know there are many other forms of caching that aren&#8217;t specific to php. Caching can happen at the client level just like it can happen at server level, not just at the code.</p>
<p>Feel free to leave any questions, comments, thoughts on this topic and thanks for reading.</p>
<p>*edit: Updated my math on improvement times plus added requests example from <a title="Wiseguy" href="http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/#comment-528" target="_self">Wiseguy</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>
