<?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</title>
	<atom:link href="http://www.joeyrivera.com/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>How to build an Adobe AIR Badge</title>
		<link>http://www.joeyrivera.com/2010/how-to-build-adobe-air-badge/</link>
		<comments>http://www.joeyrivera.com/2010/how-to-build-adobe-air-badge/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 14:52:07 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[badge]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=593</guid>
		<description><![CDATA[NOTE: This article was written with AIR 1.5 in mind. I can&#8217;t say if the following information will work as intended on AIR 2. If you already know how to build you own Adobe AIR badge, you won&#8217;t find much new information here. This post is more to inform users that you can in fact [...]]]></description>
			<content:encoded><![CDATA[<p>NOTE: This article was written with AIR 1.5 in mind. I can&#8217;t say if the following information will work as intended on AIR 2. If you already know how to build you own Adobe AIR badge, you won&#8217;t find much new information here. This post is more to inform users that you can in fact create your own AIR badge if you didn&#8217;t already know. When I first started working with AIR, I learned about the badge but as far as I was concerned, the badge was a black box who&#8217;s functionality was designed to remain mysterious.  The badge I used was the one <a title="Grant Skinner's website" href="http://www.gskinner.com/">Grant Skinner</a> created and you can get more information from <a title="About the Badge" href="http://www.adobe.com/devnet/air/articles/badge_for_air.html">Adobe</a> on how to use it. For a long time this badge worked well but finally the time has come where I need to make it behave a bit differently so I decided to do a bit of research.</p>
<p>After doing a few Google searches, I found a link to Adobe&#8217;s site with all the technical information on how to create your own AIR badge! I was completely surprised that I never even thought about the possibility that I could write my own badge&#8230; not sure what I was thinking. Nothing is more fun that reinventing the wheel right? After looking at the <a title="Adobe AIR 1.5 Badge" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e15.html">specifications</a>, I realized it wasn&#8217;t too bad and started to plan out a logical flow on how my badge was supposed to work.</p>
<h2>Requirements</h2>
<p>My current badge has the following issue: a user installs my app through the badge, every time after that point that the user comes back to the badge, they have to &#8216;install&#8217; the app again even thought it was already installed. Instead, I want the badge to sense if the application is installed and if so, launch it (I haven&#8217;t spend much time looking into Grants Badger app but I think it&#8217;ll let you do this as well if used correctly&#8230; I think). The logic for the new badge should be:</p>
<ol>
<li>Check if AIR is installed (If not, install)</li>
<li>Check if my app is installed (If not install)</li>
<li>Launch my app</li>
</ol>
<h2>Setup</h2>
<p>I&#8217;ll be using Flash CS3 since that&#8217;s what I have available to me for this tutorial and I am making the assumption you already know how to use Flash, understand ActionScript 3, and have an AIR app to test. Open Flash and create a new AS3 file and save it in some folder. Now attach a class called &#8216;Badge&#8217; to your file that extends MovieClip. Your class should look like the following:</p>
<div class="dean_ch" style="white-space: wrap;">package<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Badge <span class="kw3">extends</span> <span class="kw3">MovieClip</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Badge<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">trace</span><span class="br0">&#40;</span><span class="st0">&#8216;hi&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>I added a trace in the constructor so I can make sure my class is working. When you test your badge you should see &#8216;hi&#8217; in your output window. Now we are ready to continue.<span id="more-593"></span></p>
<h2>air.swf</h2>
<p>Adobe created a file called air.swf that resides on their server at http://airdownload.adobe.com/air/browserapi/air.swf. This file contains all the functionality required to interact with AIR files through your badge. It can check to see if you have air installed on the local machine and install it, it can check to see if an air app is installed on the local machine and install it or launch. It does it all so the first step in creating a badge is to load this file so you can call it&#8217;s methods.</p>
<p>All we need to do is create a Loader instance, add an event listener to alert us when it&#8217;s done loading the air.swf file and call the load method passing in the url as a URLRequest. The code is below with all the required imports:</p>
<div class="dean_ch" style="white-space: wrap;">package<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">Event</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Loader</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">net</span>.<span class="me1">URLRequest</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Badge <span class="kw3">extends</span> <span class="kw3">MovieClip</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> _air:<span class="kw3">Object</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Badge<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw2">var</span> loader:Loader = <span class="kw2">new</span> Loader<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loader.<span class="me1">contentLoaderInfo</span>.<span class="me1">addEventListener</span><span class="br0">&#40;</span>Event.<span class="me1">INIT</span>, airSwfLoaded<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loader.<span class="kw3">load</span><span class="br0">&#40;</span><span class="kw2">new</span> URLRequest<span class="br0">&#40;</span><span class="st0">&#8216;http://airdownload.adobe.com/air/browserapi/air.swf&#8217;</span><span class="br0">&#41;</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="kw3">private</span> <span class="kw2">function</span> airSwfLoaded<span class="br0">&#40;</span><span class="kw3">e</span>:Event<span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">this</span>._air = <span class="kw3">e</span>.<span class="kw3">target</span>.<span class="me1">content</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span><span class="br0">&#40;</span><span class="kw3">this</span>._air.<span class="me1">getStatus</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>Test the above code and in your output you should see one of the following <a title="Different status responses" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e15.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7c98">status responses</a> (taken from Adobe&#8217;s site):</p>
<table border="1" cellspacing="0" cellpadding="4">
<thead>
<tr>
<th id="d17e28828" width="NaN%" valign="top">String value</th>
<th id="d17e28831" width="NaN%" valign="top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td width="NaN%" valign="top"><samp>&#8220;available&#8221;</samp></td>
<td width="NaN%" valign="top">The runtime can be installed on this computer but currently it is not installed.</td>
</tr>
<tr>
<td width="NaN%" valign="top"><samp>&#8220;unavailable&#8221;</samp></td>
<td width="NaN%" valign="top">The runtime cannot be installed on this computer.</td>
</tr>
<tr>
<td width="NaN%" valign="top"><samp>&#8220;installed&#8221;</samp></td>
<td width="NaN%" valign="top">The runtime is installed on this computer.</td>
</tr>
</tbody>
</table>
<h2>Handling the response</h2>
<p>Now that we have a status, we can tell the badge to handle it in the appropriate manner. The first status we need to handle is &#8216;available&#8217;. This means AIR is not installed on the machine but can be. By default, AIR needs to be installed before installing an AIR app so in this scenario, all we need to call is install on our app and AIR will be installed first automatically. Here is the <strong>tricky part</strong>, we can&#8217;t automatically call install on an AIR app, it is not allowed. <span style="text-decoration: underline;">You can only call install via a user initiated event such as a button click</span>.</p>
<p>If the status is unavailable, then we can&#8217;t do much other than let the user know they can&#8217;t install AIR on their machine. If the status is installed, then the user already has AIR installed and we need to check if they have our app installed. If they do not, we install it and let them launch it. If they do have it installed, we let them launch it. Below is the complete code that does all the above:</p>
<div class="dean_ch" style="white-space: wrap;">package<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">Event</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Loader</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">MouseEvent</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">net</span>.<span class="me1">URLRequest</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> fl.<span class="me1">controls</span>.<span class="kw3">Button</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Badge <span class="kw3">extends</span> <span class="kw3">MovieClip</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> _air:<span class="kw3">Object</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">var</span> _myButton:<span class="kw3">Button</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> const APPID:<span class="kw3">String</span> = <span class="st0">&#8216;YOUAPPID&#8217;</span>; <span class="co1">// replace with your app id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> const PUBID:<span class="kw3">String</span> = <span class="st0">&#8216;123123123123123123123123.1&#8242;</span>; <span class="co1">// replace with your publisher id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> const APPURL:<span class="kw3">String</span> = <span class="st0">&#8216;http://www.yourdomain.com/YOUAIRAPP.air&#8217;</span>; <span class="co1">// replace with your app url</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> const APPRUNTIME:<span class="kw3">String</span> = <span class="st0">&#8216;1.5&#8242;</span>; <span class="co1">// I&#8217;m using 1.5 as a minimum requirement for this example</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> const AIRSWF:<span class="kw3">String</span> = <span class="st0">&#8216;http://airdownload.adobe.com/air/browserapi/air.swf&#8217;</span>; <span class="co1">// adobe&#8217;s file</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Badge<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw2">var</span> loader:Loader = <span class="kw2">new</span> Loader<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loader.<span class="me1">contentLoaderInfo</span>.<span class="me1">addEventListener</span><span class="br0">&#40;</span>Event.<span class="me1">INIT</span>, airSwfLoaded<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loader.<span class="kw3">load</span><span class="br0">&#40;</span><span class="kw2">new</span> URLRequest<span class="br0">&#40;</span><span class="kw3">this</span>.<span class="me1">AIRSWF</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>._myButton = <span class="kw2">new</span> <span class="kw3">Button</span><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="kw3">this</span>.<span class="me1">addChild</span><span class="br0">&#40;</span><span class="kw3">this</span>._myButton<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="kw3">private</span> <span class="kw2">function</span> airSwfLoaded<span class="br0">&#40;</span><span class="kw3">e</span>:Event<span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">this</span>._air = <span class="kw3">e</span>.<span class="kw3">target</span>.<span class="me1">content</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span><span class="br0">&#40;</span><span class="kw3">this</span>._air.<span class="me1">getStatus</span><span class="br0">&#40;</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">case</span> <span class="st0">&#8216;available&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// install app</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">installApp</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;unavailable&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// AIR not supported on this system</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="st0">&#8216;installed&#8217;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// check if app is installed</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>.<span class="me1">checkApp</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;<br />
&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; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">function</span> checkApp<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">this</span>._air.<span class="me1">getApplicationVersion</span><span class="br0">&#40;</span><span class="kw3">this</span>.<span class="me1">APPID</span>, <span class="kw3">this</span>.<span class="me1">PUBID</span>, checkAppCallback<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="kw3">private</span> <span class="kw2">function</span> checkAppCallback<span class="br0">&#40;</span><span class="kw3">version</span>:<span class="kw3">String</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">version</span> == <span class="kw2">null</span><span class="br0">&#41;</span> <span class="co1">// app is not installed</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="kw3">this</span>._myButton.<span class="me1">label</span> = <span class="st0">&quot;Install&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>._myButton.<span class="me1">addEventListener</span><span class="br0">&#40;</span>MouseEvent.<span class="me1">CLICK</span>, installApp<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</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="kw3">this</span>._myButton.<span class="me1">label</span> = <span class="st0">&quot;Launch&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">this</span>._myButton.<span class="me1">addEventListener</span><span class="br0">&#40;</span>MouseEvent.<span class="me1">CLICK</span>, launchApp<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="kw3">private</span> <span class="kw2">function</span> installApp<span class="br0">&#40;</span><span class="kw3">e</span>:Event = <span class="kw2">null</span><span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">this</span>._air.<span class="me1">installApplication</span><span class="br0">&#40;</span><span class="kw3">this</span>.<span class="me1">APPURL</span>, <span class="kw3">this</span>.<span class="me1">APPRUNTIME</span>, <span class="kw2">new</span> <span class="kw3">Array</span><span class="br0">&#40;</span><span class="br0">&#41;</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="kw3">private</span> <span class="kw2">function</span> launchApp<span class="br0">&#40;</span><span class="kw3">e</span>:Event<span class="br0">&#41;</span>:<span class="kw3">void</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="kw3">this</span>._air.<span class="me1">launchApplication</span><span class="br0">&#40;</span><span class="kw3">this</span>.<span class="me1">APPID</span>, <span class="kw3">this</span>.<span class="me1">PUBID</span>, <span class="kw2">new</span> <span class="kw3">Array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>I added a button that depending on the status will display the appropriate label and call the corresponding method. If the status is available we know that my app is probably not installed (since AIR is not installed) so I tell my button to call the install app method. The install app method calls the installApplication method from the air.swf file and passes the following 3 paramets: the url of the app you are trying to install, the AIR runtime required for this app, and an array of parameters required for this app if any (make sure to modify those variables to match your needs). When a user clicks on the button, they will be asked to install AIR, install the AIR application, and allowed to start it.</p>
<p>If the status is installed, we call the check app method to see if our app is already installed on the users machine by seeing what version of the app is installed. A null version means that the app is not installed. If installed, our button will launch the application and if not, we call the install app method that I just described above. The launch application method takes in three parameters: the application id, the publisher id and a array of parameters if the application requires it. <span style="text-decoration: underline;">NOTE</span>: Your AIR application MUST have <a title="BrowserInvocation Information from Adobe" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118676a5d46-8000.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7e19">allowBrowserInvocation</a> set to true in it&#8217;s AIR application descriptor xml file for the badge to be able to launch your AIR application.</p>
<h5>Finding your application id</h5>
<p>Simply go to your AIR application&#8217;s folder and open the descriptor xml file. Look for the id node and that&#8217;s the id you want to use.</p>
<h5>Finding your publisher id</h5>
<p>This one was a bit trickier. First you need to install your AIR application on your system. Once installed, go to the folder where your application was installed and inside there will be a META-INF folder. Inside that folder there is a AIR folder with a publisherid file. Open that file and the string inside is your publisher id. For example: c:\program files\myairapp\META-INF\AIR\publisherid</p>
<p>That should do it. At this point you should have a basic working AIR badge. Now you can customize it any ways you like. Hope you all find this helpful! Feel free to leave any questions or comments.</p>
<h2>Resources:</h2>
<p><a title="Adobe Links" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e15.html">http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e15.html</a></p>
<p><a title="Adobe Links" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7c9c">http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7c9c</a></p>
<p><a title="Adobe Links" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff0.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7cca">http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff0.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7cca</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/how-to-build-adobe-air-badge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What have I been up to recently&#8230;</title>
		<link>http://www.joeyrivera.com/2010/what-have-i-been-up-to-recently/</link>
		<comments>http://www.joeyrivera.com/2010/what-have-i-been-up-to-recently/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 15:32:18 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=585</guid>
		<description><![CDATA[Last month was an action packed month for me. I had a few events going on and lots of work to get done.
Atlanta PHP User Group
We had a really cool presentation on load testing using JMeter and Xdebug by Brian DeShong. Load testing and profiling are very important to help identify possible bottlenecks in your [...]]]></description>
			<content:encoded><![CDATA[<p>Last month was an action packed month for me. I had a few events going on and lots of work to get done.</p>
<h2>Atlanta PHP User Group</h2>
<p>We had a really cool <a href="http://atlantaphp.org/archive/242">presentation</a> on load testing using <a href="http://jakarta.apache.org/jmeter/">JMeter</a> and <a href="http://xdebug.org/">Xdebug</a> by <a href="http://www.deshong.net/">Brian DeShong</a>. Load testing and profiling are very important to help identify possible bottlenecks in your application/server before reaching a breaking point. JMeter allows a user to setup different scenarios to run with varying loads (number of users, ramp up time). It&#8217;s pretty fancy with all the options you can do such as submit variables to pages to simulate login ins to an application and tracking sessions. Xdebug lets us analyze logs to see what was going on in your application to easily spot which part of the execution process took the most amount of time. At that point, you can look at your code to see how to improve that particular process.</p>
<p>At work we have an outside firm doing our testing/load testing so it was nice learning about JMeter so eventually we can start doing some of our own load tests for things we need done asap. I currently use Zend Studio&#8217;s profiler to profile my applications so I probably won&#8217;t be using Xdebug any time soon.</p>
<h2>TEK-X</h2>
<p><img class="alignleft" title="TEK-X Conference" src="http://tek.phparch.com/wp-content/themes/tekx/images/header-logo.png" alt="" width="300" height="100" />I asked around our local user group what conference they would recommend if they could only attend one PHP conference and this was the one I heard the most good things about. This was my first time attending a PHP conference and it was WELL worth it. The sessions were great with three tracks daily to choose from. The conference was small enough where you could spend time with the presenters interacting and asking questions. I met a bunch of new people which made the whole experience that much better. There was always something to do during presentations as well as after hours.</p>
<p>This is the web site for <a href="http://tek.phparch.com/">TEX-K</a> if you want more info or want to take a look at the <a href="http://tek.phparch.com/schedule/">schedule</a>. Some of my favorite were the two Flex sessions by <a href="http://caseysoftware.com/blog">Keith Casey</a> since I want to start doing more Flex and the Lost Art of Simplicty by <a href="http://www.joshholmes.com/blog/">Josh Holmes</a> was interesting as well. It was really nice having a bunch of Adobe and Microsoft people there. They were all great and helpful. We had been having some server hiccups at work and the guys at Microsoft were extremely helpful in trying to help us figure things out. We also learned from various people (both the MS and PHP crowd) that we (at work) should start using IIS instead of Apache for Windows. Microsoft has been spending resources in working with the PHP team to make sure things run smoother with PHP on IIS for Windows than before.</p>
<p>Two thumbs up for Microsoft and Adobe for being there and supporting the community (and for the drinks and dinners :p) . I&#8217;ll definitely try to go next year again.</p>
<h2>Flash Builder for PHP</h2>
<p><img class="alignleft" title="Flash Builder" src="http://www.adobe.com/products/flex/images/overview_flashbuildermnemonic.jpg" alt="" width="80" height="80" />I took a one day-8 hour course on using Flash Builder and wow&#8230; I&#8217;m sold. After working on Flash for so many years, Flex is just too amazing to ignore. The class was taught by Adobe certified <a href="http://stallons.com/bio.html">Jeanette Stallons</a> and it was a small class which was great for us since we could get a lot more time for questions and one on one time. She did a great job keeping our attention and was very easy to follow. This was a hands on class so we each had our own computer to work the examples with.</p>
<p>The class started with us learning about the different Adobe applications, the difference between Flash/Flex, and reasoning behind changing the name Flex builder to Flash builder. Then we went through the basics of the IDE and how to setup a project and what the different folders and files are for. Next is when things got fun. We started creating an application that communicates with the database through PHP. We did all the code manually to better appreciate the last lesson which was creating the exact same application in an automated fashion with literally only a few lines of code at most. That was the coolest part of this class, how easy it is to use the wizards (that actually spit out good code!) to be able to just click and drag and have everything working correctly in such a <span style="text-decoration: underline;">short amount of time</span>.</p>
<p>I already <a href="http://www.adobe.com/products/flashbuilder/">downloaded</a> the two month trial from the Adobe&#8217;s site and have been playing around with Flash Builder at work and at home.</p>
<h2>Google AdWords API v13 to v2009</h2>
<p>A few years ago I wrote an application that heavily uses the Google Adwords API. It worked without me touching it for years until recently Google <a href="http://code.google.com/apis/adwords/articles/migrating.html">changed</a> their Adwords API and my app completely stopped working. This was my fault of course since many months ago Google emailed me letting me know this was going to happen but at the time I figured there wouldn&#8217;t be much difference between both versions so I didn&#8217;t pay much attention to it&#8230; boy was I wrong.</p>
<p>The new API v2009 is very different since you call things differently now and many of the old services I was using no longer exist in the new version. I spent some time trying to rework my code to use the new calls but that was not working well for me. It just seemed as if I was wasting time instead of just starting over with a clean rewrite. Fortunately for me, after doing some research, I found that Google had already created a <a href="http://code.google.com/apis/adwords/v2009/docs/clientlibraries.html">client library</a> for PHP that already did all the heavy lifting code to interact with the services. I downloaded the library, ran a couple tests and everything was working perfectly. All I had to do was rewrite the application using the client library and everything is running smoothly again.</p>
<p>Thanks Google! You saved me a lot of time but don&#8217;t change your API again <img src='http://www.joeyrivera.com/blog_new/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<h2>My Birthday</h2>
<p><img class="alignleft" title="Garmin 405 Watch" src="https://static.garmincdn.com/en/products/010-00658-10/g/cf-lg.jpg" alt="" width="300" height="300" />Not much to mention here other than it was my birthday last month as well so had dinners with parents and drinks with friends. I have been running a lot lately so I bought myself a nice new watch with my birthday money: <a href="https://buy.garmin.com/shop/shop.do?pID=11039">Garmin 405</a>. I saw this watch on sale on <a href="http://www.slickdeals.net/">slickdeals.net</a> for under $200 and I couldn&#8217;t resist. I&#8217;ve used it a couple times already and it&#8217;s great. The GPS seems to be working flawlessly for me so far and all the features it brings are neat to play with. My biggest sellers were: GPS to track my distance and pace and the heart rate monitor.</p>
<p><a href="http://www.atlantatrackclub.org/peachtree.htm">Peachtree Road Race</a>, here I come!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/what-have-i-been-up-to-recently/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two thumbs up for the wifey!</title>
		<link>http://www.joeyrivera.com/2010/two-thumbs-up-for-the-wifey/</link>
		<comments>http://www.joeyrivera.com/2010/two-thumbs-up-for-the-wifey/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 19:11:04 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[ashley fleishel]]></category>
		<category><![CDATA[ashley rivera]]></category>
		<category><![CDATA[kroger]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=579</guid>
		<description><![CDATA[So my wife submitted a design for an eco-friendly bag contest for Kroger late last year. There were over 46,000 entries nation wide and she ended up winning second place!!! Great job sweets!

Starting next month (April), if you shop at Kroger, you may be able to purchase her bag from your local Kroger store. Here [...]]]></description>
			<content:encoded><![CDATA[<p>So my wife submitted a design for an <a href="http://www.designareusablebag.com/vote-for-designs/top-10.aspx">eco-friendly bag contest for Kroger</a> late last year. There were over 46,000 entries nation wide and she ended up winning second place!!! Great job sweets!</p>
<p style="text-align: center;">
<p>Starting next month (April), if you shop at Kroger, you may be able to purchase her bag from your local Kroger store. Here is an article that just came out today from a local magazine:</p>
<p><a href="http://www.mdjonline.com/view/full_story/6794712/article-Marietta-graphic-designer-takes-2nd-in-Kroger-s-reusable-bag-competition?instance=home_news_1st_right">http://www.mdjonline.com/view/full_story/6794712/article-Marietta-graphic-designer-takes-2nd-in-Kroger-s-reusable-bag-competition?instance=home_news_1st_right</a></p>
<p>Feel free to visit Ashley&#8217;s blog and let her know she did a great job: <a href="http://ashleycf.wordpress.com/">Ashley&#8217;s Blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/two-thumbs-up-for-the-wifey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Dale Carnegie High Impact Presentations Experience/Review</title>
		<link>http://www.joeyrivera.com/2010/dale-carnegie-high-impact-presentations-reivew/</link>
		<comments>http://www.joeyrivera.com/2010/dale-carnegie-high-impact-presentations-reivew/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 18:22:22 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[dale carnegie]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[reivew]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=566</guid>
		<description><![CDATA[Wow&#8230; I can&#8217;t stress enough how much improvement I made over the course of two days from taking this program from Dale Carnegie. Before I continue with this post I want to thank Julianne Rivera (Sr. Business Consultant) for encouraging me to take this class. Had it not been for her, my audience would have paid the [...]]]></description>
			<content:encoded><![CDATA[<p>Wow&#8230; I can&#8217;t stress enough how much improvement I made over the course of two days from taking this program from <a title="Dale Carnegie Web Site" href="http://www.dalecarnegie.com/">Dale Carnegie</a>. Before I continue with this post I want to thank <a title="Julianne Rivera's Email" href="mailto:julianne.rivera@dalecarnegie.com">Julianne Rivera</a> (Sr. Business Consultant) for encouraging me to take this class. Had it not been for her, my audience would have paid the price. I also want to thank Ercell Charles and April Farlow for being great coaches throughout this program and doing a fantastic job. This was my first time taking a Dale Carnegie class and it won&#8217;t be my last. <strong>Make sure to watch the before and after videos below to see why</strong>.</p>
<h4>Why did I want to take this class?</h4>
<p>Every time I receive a comment on this blog from my users letting me know that what I wrote helped them in some way, I find it extremely rewarding. I like being able to share my thoughts, knowledge, and experience with others and have decided I want to start presenting to local user groups to further expand my reach. I know my material, but my presentation skills were lacking. I have my first presentation coming up for the <a title="Atlanta PHP User Group" href="http://www.atlantaphp.org/">Atlanta PHP User Group</a> and I want to make sure I don&#8217;t bore my audience. I did a quick dry run to test my presentation and it wasn&#8217;t very energetic&#8230; it was actually pretty dull. So when the opportunity to take a Dale Carnegie class on presentations presented itself, I took it.<span id="more-566"></span></p>
<h4>About the class</h4>
<p>The program was tough, two days from 8am to 5pm Thursday and Friday none-stop plus homework. The class consisted of 8-9 students and two coaches, Ercell Charles and April Farlow. Both coaches were extremely knowledgeable and great to work with. The focus of the class is not what our content is but how to effectively deliver our content to an audience. How to catch our audience&#8217;s attention and keep them interested throughout. How to add energy and use our voice to get points across.</p>
<p>In two days, we each presented probably 8 times, six of which were recorded. We would receive coaching during each presentation and more coaching when we watched our video afterwards. This was probably the biggest eye opener for me, watching myself on video after a presentation and watching the progression I was making with each presentation. The coaches made us do, what at the time felt like wild and crazy things, but when you watched yourself on the tape, you looked perfectly normal, more than that, you looked like a real presenter!</p>
<p>Not only were the coaches valuable but so was everyone else there. Being able to watch these other people present and interact with them was very helpful to the experience. We all helped each other with lots of positive reenforcement and it was nice watching each individual grow with each presentation. The individual who left the biggest impression with me was one who during his first presentation was very quiet and timid. He lacked confidence and you could tell he wasn&#8217;t in his comfort zone. On the second day, during his last presentation, he was a completely different person. You could not have known this man and the man from the day before were the same person. He was so confident, did an excellent job using his voice and gestured and captured his audience for the entire duration of his presentation.</p>
<p>Below are my before and after videos. Don&#8217;t focus on the content, just focus on how I am delivering the content. Focus on my voice inflection (or lack off), look at my hands and posture. You may want to watch the first then the second a couple times to really get the full experience.</p>
<h4>Before and after videos</h4>
<p>Before:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ENJ6SmCNIPI&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/ENJ6SmCNIPI&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>After:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/p5XTW3xxX6U&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/p5XTW3xxX6U&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>I&#8217;ve watched these two videos over and over again with a huge smile on my face and excitement to see the after me. I know I can do much better now to keep my audience entertained! And the best part, this is just the starting point. I now have what I need to keep improving.</p>
<p>The toughest part of this program was the end of the last day &#8211; the questions and answers session. Very tough questions were asked to each of us, questions that we didn&#8217;t necessarily want to answer about us as individuals, our company, or our products and service. Some were tough because they dealt with uncomfortable issues, others were in an attempt to incite anger or discomposure. These questions needed to be asked to teach us how to deal with them in a very professional manner. We were taught not to use &#8216;fighting words&#8217; (like Ercell likes to call them) in our response. We were taught how to deal with individuals who try to bring us down by keeping our credibility and sticking to our values.</p>
<p>Overall I give Ercell, April, and Dale Carnegie an A+ for this High Impact Presentation program. It was very rewarding and I encourage any of you who currently give presentations at work or user groups as well as those like me who want to start presenting to look into this program. You will not regret taking it. If you have any questions about this program feel free to contact <a title="Julianne Rivera's Email" href="mailto:julianne.rivera@dalecarnegie.com">Julianne Rivera</a>.</p>
<p>Have you taken this program before? If so, I&#8217;d like to hear how it went.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/dale-carnegie-high-impact-presentations-reivew/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Finally gave my blog a much needed face lift!</title>
		<link>http://www.joeyrivera.com/2010/finally-gave-my-blog-a-much-needed-face-lift/</link>
		<comments>http://www.joeyrivera.com/2010/finally-gave-my-blog-a-much-needed-face-lift/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 18:38:47 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=513</guid>
		<description><![CDATA[So what do you guys think? Does it look better now? It is not finished, I still need to tweak some graphics and colors but overall I&#8217;m very pleased. I started out with a new theme: Arclite by digitalnature. It has many customization options so I haven&#8217;t had to do too much tweaking of the .css files [...]]]></description>
			<content:encoded><![CDATA[<p>So what do you guys think? Does it look better now? It is not finished, I still need to tweak some graphics and colors but overall I&#8217;m very pleased. I started out with a new theme: Arclite by <a href="http://digitalnature.ro/">digitalnature</a>. It has many customization options so I haven&#8217;t had to do too much tweaking of the .css files but there has been some. Since I blog so much about code, I finally stopped being lazy and got a code highlighter. I&#8217;m using: <a href="http://www.deanlee.cn/wordpress/code_highlighter_plugin_for_wordpress/">Dean&#8217;s Code Highlighter by</a> Dean Lee. It&#8217;s very easy to use and supports a range of different code syntax such as PHP and Actionscript. One of the reasons I decided to update my look was because I have been running an older version of WordPress and it was about time to upgrade. I&#8217;m now running 2.9.1 and it looks great. I really like the new admin back office and it is so easy to use and setup.</p>
<p>I also created my first widgets! The &#8216;Interesting Links&#8217; and &#8216;Interesting Images&#8217; on the sidebar are no longer hacks done on the themes sidebar.php file. I learned how to create a plugin in WordPress and make it into a widget. Here is what one of the widgets looks like:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="coMULTI">/*<br />
Plugin Name: JR-Images<br />
Plugin URI: http://www.joeyrivera.com<br />
Description: Show my images<br />
Version: 0.1<br />
Author: Joey Rivera<br />
Author URI: http://www.joeyrivera.com</p>
<p>&nbsp; Copyright 2010 &nbsp;Joey Rivera &nbsp;(email : joey1.rivera@gmail.com)</p>
<p>&nbsp; &nbsp; This program is free software; you can redistribute it and/or modify<br />
&nbsp; &nbsp; it under the terms of the GNU General Public License, version 2, as <br />
&nbsp; &nbsp; published by the Free Software Foundation.</p>
<p>&nbsp; &nbsp; This program is distributed in the hope that it will be useful,<br />
&nbsp; &nbsp; but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
&nbsp; &nbsp; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the<br />
&nbsp; &nbsp; GNU General Public License for more details.</p>
<p>&nbsp; &nbsp; You should have received a copy of the GNU General Public License<br />
&nbsp; &nbsp; along with this program; if not, write to the Free Software<br />
&nbsp; &nbsp; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA &nbsp;02110-1301 &nbsp;USA<br />
*/</span><br />
&nbsp;<br />
<span class="kw2">function</span> show_images<span class="br0">&#40;</span><span class="br0">&#41;</span> <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/global"><span class="kw3">global</span></a> <span class="re0">$wpdb</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$query</span> = <span class="st0">&#8216;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT image_file, image_origin, image_thumbnail<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM wp_images<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY image_id DESC<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LIMIT 6&#8242;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$results</span> = <span class="re0">$wpdb</span>-&gt;<span class="me1">get_results</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$results</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="kw1">return</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;li class=&quot;block widget widget_images&quot;&gt;&lt;div class=&quot;box&quot;&gt; &lt;div class=&quot;wrapleft&quot;&gt;&lt;div class=&quot;wrapright&quot;&gt;&lt;div class=&quot;tr&quot;&gt;&lt;div class=&quot;bl&quot;&gt;&lt;div class=&quot;tl&quot;&gt;&lt;div class=&quot;br the-content&quot;&gt;&lt;div class=&quot;titlewrap&quot;&gt;&lt;h4&gt;&lt;span&gt;Interesting Images&lt;/span&gt;&lt;/h4&gt;&lt;/div&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;ul class=&quot;blank&quot;&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$results</span> <span class="kw1">as</span> <span class="re0">$row</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;li&gt;&lt;a href=&quot;/uploader/sample/&#8217;</span> . <span class="re0">$row</span>-&gt;<span class="me1">image_file</span> . <span class="st0">&#8216;&quot; title=&quot;&#8217;</span> . <span class="re0">$row</span>-&gt;<span class="me1">image_origin</span> . <span class="st0">&#8216;&quot; rel=&quot;lightbox&quot;&gt;&lt;img src=&quot;/uploader/sample/&#8217;</span> . <span class="re0">$row</span>-/&gt;image_thumbnail . <span class="st0">&#8216;&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&#8217;</span>, <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;/ul&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/div&gt;&lt;/li&gt;&#8217;</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;<br />
<span class="kw2">function</span> register_images<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; register_sidebar_widget<span class="br0">&#40;</span><span class="st0">&quot;JR-Images&quot;</span>, <span class="st0">&quot;show_images&quot;</span><span class="br0">&#41;</span>; &nbsp; &nbsp; <br />
<span class="br0">&#125;</span><br />
&nbsp;<br />
add_action<span class="br0">&#40;</span><span class="st0">&quot;plugins_loaded&quot;</span>, <span class="st0">&quot;register_images&quot;</span><span class="br0">&#41;</span>;</div>
<p>I had to go back to all my old posts and make updates. If you find any issues anywhere, please let me know so I can fix it asap. I&#8217;ve found instances in code where there should be two &amp;&amp; and instead the code blocks shows &amp;amp;&amp;amp;. I&#8217;m currently trying to figure out why my preview button doesn&#8217;t work, hopefully I&#8217;ll figure that out soon so I can move on to changing some colors around and finally updating my &#8216;About Me&#8217; page. I hope to have some content in that page by the end of this weekend. Other than that, I hope you all enjoy the new look and am looking forward to hearing some feedback!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/finally-gave-my-blog-a-much-needed-face-lift/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automate Db Model Creation with Zend_CodeGenerator_Php_Class</title>
		<link>http://www.joeyrivera.com/2009/automate-model-creation-with-zend_codegenerator_php_class/</link>
		<comments>http://www.joeyrivera.com/2009/automate-model-creation-with-zend_codegenerator_php_class/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 19:47:35 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[codegenerator]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_codegenerator_php_class]]></category>
		<category><![CDATA[zend_db_table_abstract]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=462</guid>
		<description><![CDATA[I&#8217;m working on a new tool at work that will automate several processes for a few employees so they don&#8217;t have to spend too much time doing very repetitive tasks. This tool has to do a good bit of database manipulation so I&#8217;ve decided I&#8217;ll build it in PHP using Zend Framework.
I&#8217;ll be using Zend_Db_Table_Abstract [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a new tool at work that will automate several processes for a few employees so they don&#8217;t have to spend too much time doing very repetitive tasks. This tool has to do a good bit of database manipulation so I&#8217;ve decided I&#8217;ll build it in PHP using Zend Framework.</p>
<p>I&#8217;ll be using <a title="Zend Db Table Docs" href="http://framework.zend.com/manual/en/zend.d.table.html">Zend_Db_Table_Abstract</a> to communicate with the db tables from my project and I&#8217;ll be creating a model for each table as well to store and manipulate data. I&#8217;ll be working with lots of tables in the database and many have lots of fields.</p>
<p>I start by opening up Zend Studio on one monitor and SQL Query Analyzer on the other and get to work. The first table I want to work with is the &#8216;Student&#8217; table. I create a new file in my project called Student.php. Place it on my models/DbTable folder and inside I simply have to declare &#8216;_name&#8217; as a protected property with the value &#8216;Student&#8217; and extend &#8216;Zend_Db_Table_Abstract&#8217;. Easy enough but now I want to create the model I will be using to convert the database data into workable objects through my mapper class.</p>
<h4>Problem</h4>
<p>I create a new file called &#8216;Student.php&#8217; and save it to my models folder. I open the file up and now I have to create a property (it&#8217;s actually an array _data with all properties defined as keys inside) for each field in the Student table&#8230; all 50 of them! I have to be careful to name each correctly as well as to not accidentally miss some field. It ends up being a time consuming process and inefficient so I start looking for a better way to accomplish this.<span id="more-465"></span></p>
<h4>Solution</h4>
<p>This is where <a title="Zend CodeGenerator Php Class" href="http://framework.zend.com/manual/en/zend.codegenerator.html">Zend_CodeGenerator_Php_Class</a> comes in. This component of Zend allows you to create php code on the fly. My theory was, instead of manually creating all these files and typing all the field names (very time consuming with lots of room for error), I could use Zend_CodeGenerator_Php to create all the content of my classes and echo it on the screen so I could copy/paste. Once I had this working, I took it to the next step and included the process of saving that content to files on my project folder. After working on this last night, everything worked like a charm and my classes are easily and quickly created, mapped directly to my database structure, by simply calling one method. No room for error either and I can run this at any time!</p>
<h4>Code</h4>
<p>I&#8217;ll explain the code below. <a title="File of code below" href="http://www.joeyrivera.com/blog_files/462/file.txt">You can download the file if you like</a>.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span><br />
<span class="re0">$db</span> = Zend_Registry::<span class="me2">get</span><span class="br0">&#40;</span><span class="st0">&#8216;db&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$paths</span> = Zend_Registry::<span class="me2">get</span><span class="br0">&#40;</span><span class="st0">&#8216;paths&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$temp_path</span> = <span class="re0">$paths</span><span class="br0">&#91;</span><span class="st0">&#8216;temp&#8217;</span><span class="br0">&#93;</span>;</p>
<p><span class="co1">// get all tables in db</span><br />
<span class="re0">$tables</span> = <span class="re0">$db</span>-&gt;<span class="me1">listTables</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$tables</span> <span class="kw1">as</span> <span class="re0">$table</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// need to remove underline first, ucwords, and then remove space</span><br />
&nbsp; &nbsp; <span class="re0">$name</span> = <a href="http://www.php.net/str_replace"><span class="kw3">str_replace</span></a><span class="br0">&#40;</span><span class="st0">&#8216; &#8216;</span>, <span class="st0">&#8221;</span>, <a href="http://www.php.net/ucwords"><span class="kw3">ucwords</span></a><span class="br0">&#40;</span><a href="http://www.php.net/str_replace"><span class="kw3">str_replace</span></a><span class="br0">&#40;</span><span class="st0">&#8216;_&#8217;</span>, <span class="st0">&#8216; &#8216;</span>, <span class="re0">$table</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// create new class generator</span><br />
&nbsp; &nbsp; <span class="re0">$class</span> = <span class="kw2">new</span> Zend_CodeGenerator_Php_Class<span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// configure docblock</span><br />
&nbsp; &nbsp; <span class="re0">$docblock</span> = <span class="kw2">new</span> Zend_CodeGenerator_Php_Docblock<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; <span class="st0">&#8217;shortDescription&#8217;</span> =&gt; <span class="re0">$name</span> . <span class="st0">&#8216; model&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;tags&#8217;</span> =&gt; <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; <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;name&#8217;</span> =&gt; <span class="st0">&#8216;author&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;description&#8217;</span> =&gt; <span class="st0">&#8216;Joey Rivera&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// set name and docblock</span><br />
&nbsp; &nbsp; <span class="re0">$class</span>-&gt;<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&#8216;Ct_Model_&#8217;</span> . <span class="re0">$name</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$class</span>-&gt;<span class="me1">setDocblock</span><span class="br0">&#40;</span><span class="re0">$docblock</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// get all fields</span><br />
&nbsp; &nbsp; <span class="re0">$fields</span> = <span class="re0">$db</span>-&gt;<span class="me1">describeTable</span><span class="br0">&#40;</span><span class="re0">$table</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// want to track primary ids for table</span><br />
&nbsp; &nbsp; <span class="re0">$primary</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// add to columns each field with a default value</span><br />
&nbsp; &nbsp; <span class="re0">$columns</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">foreach</span><span class="br0">&#40;</span><span class="re0">$fields</span> <span class="kw1">as</span> <span class="re0">$field</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if int field default to 0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$columns</span><span class="br0">&#91;</span><span class="re0">$field</span><span class="br0">&#91;</span><span class="st0">&#8216;COLUMN_NAME&#8217;</span><span class="br0">&#93;</span><span class="br0">&#93;</span> =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/strpos"><span class="kw3">strpos</span></a><span class="br0">&#40;</span><span class="re0">$field</span><span class="br0">&#91;</span><span class="st0">&#8216;DATA_TYPE&#8217;</span><span class="br0">&#93;</span>, <span class="st0">&#8216;int&#8217;</span><span class="br0">&#41;</span> !== <span class="kw2">false</span> ? <span class="nu0">0</span> : <span class="st0">&#8221;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// track primary field(s) for table</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$field</span><span class="br0">&#91;</span><span class="st0">&#8216;PRIMARY&#8217;</span><span class="br0">&#93;</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">$primary</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$field</span><span class="br0">&#91;</span><span class="st0">&#8216;COLUMN_NAME&#8217;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="co1">// add data array property to class</span><br />
&nbsp; &nbsp; <span class="re0">$class</span>-&gt;<span class="me1">setProperty</span><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; <span class="st0">&#8216;name&#8217;</span> =&gt; <span class="st0">&#8216;_data&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;visibility&#8217;</span> =&gt; <span class="st0">&#8216;protected&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;defaultValue&#8217;</span> =&gt; <span class="re0">$columns</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;docblock&#8217;</span> =&gt; <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; <span class="st0">&#8216;tags&#8217;</span> =&gt; <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="kw2">new</span> Zend_CodeGenerator_Php_Docblock_Tag<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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;name&#8217;</span> =&gt; <span class="st0">&#8216;var&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;description&#8217;</span> =&gt; <span class="st0">&#8216;array Maps to all fields in table&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$class</span>-&gt;<span class="me1">generate</span><span class="br0">&#40;</span><span class="br0">&#41;</span> . PHP_EOL;<br />
&nbsp; &nbsp; &nbsp; &nbsp; file_put_contents<span class="br0">&#40;</span><span class="re0">$temp_path</span> . <span class="re0">$name</span> . <span class="st0">&#8216;.php&#8217;</span>, <span class="st0">&#8216;&lt;?php&#8217;</span> . PHP_EOL . <span class="re0">$class</span>-&gt;<span class="me1">generate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// create zend_db_table_abstract</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db_class</span> = <span class="kw2">new</span> Zend_CodeGenerator_Php_Class<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db_class</span>-&gt;<span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&#8216;Ct_Model_DbTable_&#8217;</span> . <span class="re0">$name</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db_class</span>-&gt;<span class="me1">setDocblock</span><span class="br0">&#40;</span><span class="kw2">new</span> Zend_CodeGenerator_Php_Docblock<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; <span class="st0">&#8217;shortDescription&#8217;</span> =&gt; <span class="re0">$name</span> . <span class="st0">&#8216; db table abstract&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;tags&#8217;</span> =&gt; <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; <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;name&#8217;</span> =&gt; <span class="st0">&#8216;author&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;description&#8217;</span> =&gt; <span class="st0">&#8216;Joey Rivera&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db_class</span>-&gt;<span class="me1">setExtendedClass</span><span class="br0">&#40;</span><span class="st0">&#8216;Zend_Db_Table_Abstract&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db_class</span>-&gt;<span class="me1">setProperty</span><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; <span class="st0">&#8216;name&#8217;</span> =&gt; <span class="st0">&#8216;_name&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;visibility&#8217;</span> =&gt; <span class="st0">&#8216;protected&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;defaultValue&#8217;</span> =&gt; <span class="re0">$table</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;docblock&#8217;</span> =&gt; <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;tags&#8217;</span> =&gt; <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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Zend_CodeGenerator_Php_Docblock_Tag<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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;name&#8217;</span> =&gt; <span class="st0">&#8216;var&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;description&#8217;</span> =&gt; <span class="st0">&#8217;string Name of db table&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <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">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <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">$primary</span><span class="br0">&#41;</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">$db_class</span>-&gt;<span class="me1">setProperty</span><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;name&#8217;</span> =&gt; <span class="st0">&#8216;_primary&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;visibility&#8217;</span> =&gt; <span class="st0">&#8216;protected&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;defaultValue&#8217;</span> =&gt; <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$primary</span><span class="br0">&#41;</span> &gt; <span class="nu0">1</span> ? <span class="re0">$primary</span> : <span class="re0">$primary</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;docblock&#8217;</span> =&gt; <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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;tags&#8217;</span> =&gt; <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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Zend_CodeGenerator_Php_Docblock_Tag<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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;name&#8217;</span> =&gt; <span class="st0">&#8216;var&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;description&#8217;</span> =&gt; <span class="st0">&#8217;string or array of fields in table&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</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">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &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; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$db_class</span>-&gt;<span class="me1">generate</span><span class="br0">&#40;</span><span class="br0">&#41;</span> . PHP_EOL;<br />
&nbsp; &nbsp; &nbsp; &nbsp; file_put_contents<span class="br0">&#40;</span><span class="re0">$temp_path</span> . <span class="st0">&#8216;DbTable/&#8217;</span> . <span class="re0">$name</span> . <span class="st0">&#8216;.php&#8217;</span>, <span class="st0">&#8216;&lt;?php&#8217;</span> . PHP_EOL . <span class="re0">$db_class</span>-&gt;<span class="me1">generate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
<p>I start out by getting some needed variables such as my $db adapter and paths that I will use to store my files in. For this example I am using MySQL (5.1.x) database and Zend Framework 1.9.5. If you are not familiar on how to setup your database adapter <a title="Zend Db Adapter Doc" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://framework.zend.com/manual/en/zend.db.html#zend.db.adapter.connecting.constructor');" href="http://framework.zend.com/manual/en/zend.db.html#zend.db.adapter.connecting.constructor">here is the documentation</a>.</p>
<p>The next step is to call listTables on the db adapter to get an array of all the tables in the database. We want to loop through the array and create two files for each table: an object model and a db table abstract. Each file has a corresponding instance of Zend_CodeGenerator_Php_Class. The first one we create in the code is for the object model. The docblock is the optional comments for the class if you want them. setName is the name you want for the class. In this case I&#8217;m using &#8216;Ct_Model_$name&#8217; where name is the name of the table without any underscores and with the first letter of each word in uppercase. For example, if the table name is: &#8216;user_info&#8217;, name is &#8216;UserInfo&#8217;.</p>
<p>The next information I need is all the fields for that table so I can add them to my data array for each model. Calling describeTable(&#8216;tableName&#8217;) returns that. Now that I have my array with all the fields information for this first table, so I loop through to:</p>
<ul>
<li>assign names and default value(s) of 0 for an int field type or null for anything else into the columns array.</li>
<li>track the primary key(s) for each table. Some tables can have more than one.</li>
</ul>
<p>setProperty is where we create the protected data property array for this class. The name of the property is &#8216;_data&#8217; and the default value is the array we just created &#8216;columns&#8217;. You can also add a docblock to the property which I did here. Since there is no Zend_CodeGenerator_Php_Docblock_Tag_Property I just used the default Tag class passing it name &#8216;var&#8217;. Had I used Zend_CodeGenerator_Php_Docblock_Tag_Param, my comments would have shown &#8216;@param&#8217; when it is really &#8216;@var&#8217;. Try it and you&#8217;ll see what I mean.</p>
<p>Our first class for the model is now complete! I&#8217;m echoing it to the screen so I can see it when I view-source or just use Zend_Debug::dump() instead to see it formatted. The next line saves the newly generated code to a file at a temp_path location. It&#8217;s important to add &#8216;&lt;?php&#8217; before class-&gt;generate() so your file have the php tag in them.</p>
<p>The next part of the code creates the second class that extends <a title="Zend Db Table Abstract Doc" href="http://framework.zend.com/manual/en/zend.db.table.html">Zend_Db_Table_Abstract</a>. I won&#8217;t go into detail with what is happening there since it&#8217;s very similar to the above. If you have any questions do feel free to ask. That&#8217;s pretty much it. Run this code, make sure you have your directories created and after executing you should now have two files for each table in your database.</p>
<p>Here is an example of what you should see after running the page:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="coMULTI">/**<br />
&nbsp;* Bio model<br />
&nbsp;*<br />
&nbsp;* @author Joey Rivera<br />
&nbsp;*/</span><br />
<span class="kw2">class</span> Ct_Model_Bio<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* @var array Maps to all fields in table<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span class="re0">$_data</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;bio_id&#8217;</span> =&gt; <span class="nu0">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;user_id&#8217;</span> =&gt; <span class="nu0">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;bio_type_id&#8217;</span> =&gt; <span class="nu0">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;title&#8217;</span> =&gt; <span class="kw2">null</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;content&#8217;</span> =&gt; <span class="kw2">null</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;last_update&#8217;</span> =&gt; <span class="kw2">null</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;enabled&#8217;</span> =&gt; <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="coMULTI">/**<br />
&nbsp;* Bio db table abstract<br />
&nbsp;*<br />
&nbsp;* @author Joey Rivera<br />
&nbsp;*/</span><br />
<span class="kw2">class</span> Ct_Model_DbTable_Bio <span class="kw2">extends</span> Zend_Db_Table_Abstract<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* @var string Name of db table<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span class="re0">$_name</span> = <span class="st0">&#8216;bio&#8217;</span>;<br />
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* @var string or array of fields in table<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; protected <span class="re0">$_primary</span> = <span class="st0">&#8216;bio_id&#8217;</span>;<br />
<span class="br0">&#125;</span></div>
<p>This is a work in progress since I&#8217;m still trying different things. After I finished writing this code I went back to the zend docs and noticed there is <a title="Zend CodeGenerator Php File Doc" href="http://framework.zend.com/manual/en/zend.codegenerator.examples.html#zend.codegenerator.examples.file">Zend_CodeGenerator_Php_File</a>. Seems to do the same thing I did above with file_put_contents. Feel free to try that instead.</p>
<h4>Conclusion</h4>
<p>I really enjoy the flexibility of using this method instead of typing everything out myself. It&#8217;s quicker with a lot less room for error. I&#8217;m sure there are already other programs/apps out there that do this but hey, it&#8217;s more fun to reinvent the wheel! Plus I learned about another Zend Framework module that I had not used before.</p>
<p>EDIT:</p>
<p>I had to make to small edits to this post to work more efficiently. The first was to change the line where we set the default value of each field for the columns array to &#8221; instead of null. The second was to set the primary property only if there was a primary field found on that table since not every table will always have one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/automate-model-creation-with-zend_codegenerator_php_class/feed/</wfw:commentRss>
		<slash:comments>21</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>
		<item>
		<title>Implementing Vanity URLs in PHP w/ Zend Framework</title>
		<link>http://www.joeyrivera.com/2009/implementing-vanity-urls-in-php-w-zend-framework/</link>
		<comments>http://www.joeyrivera.com/2009/implementing-vanity-urls-in-php-w-zend-framework/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 16:45:15 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[dispatcher]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[vanity]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=426</guid>
		<description><![CDATA[One of the reasons why people like vanity url&#8217;s is because they are easy to remember. For example take the following url:
http://www.somesocialsite.com/?user_id=123456789&#38;page=somepage
If this was the url to my page in some social network site, there&#8217;s no way I could remember it nor would I be able to easily share the url with others unless I [...]]]></description>
			<content:encoded><![CDATA[<p>One of the reasons why people like vanity url&#8217;s is because they are easy to remember. For example take the following url:</p>
<p>http://www.somesocialsite.com/?user_id=123456789&amp;page=somepage</p>
<p>If this was the url to my page in some social network site, there&#8217;s no way I could remember it nor would I be able to easily share the url with others unless I sent them the link. Now, if I could instead create a vanity url that looked like the following:</p>
<p>http://www.somesocialsite.com/joeyrivera</p>
<p>it would be much easier to remember and to share with others. Not only that but now I have a much more search engine friendly url with keywords that I would like to be found under &#8211; but ignore the search engine benefits for now.</p>
<h4>Why</h4>
<p>I&#8217;m currently working on an application that can benefit from vanity urls for the reasons mentioned above so I decided to spend some time thinking of ways to implement this. The first way that came to my mind was using <a href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html">mod_rewrite</a>. Mod rewrite lets you manipulate urls. For example, you can write rules in your <a href="http://wiki.apache.org/httpd/Htaccess">.htaccess</a> file so when a user goes to <em>http://www.somesocialsite.com/joeyrivera</em> it really calls <em>http://www.somesocialsite.com/search.php?user=joeyrivera</em> or in zend the request would be more like <em>http://www.somesocialsite.com/search/user/name/joeyrivera<span id="more-426"></span><br />
</em></p>
<h4>Not mod_rewrite</h4>
<p>We could make mod_rewrite work but zend already routes all traffic to the index.php file and to me, having this external-to-the-app rules just seems a bit messy. Plus, it&#8217;ll be tricky to tell mod_rewrite what urls are valid and which should be handled be zend directly. In the example above, what if joeyrivera was a legitimate controller name? In that case, zend should handle the request.</p>
<h4>Zend&#8230; yes!</h4>
<p>So then I decided I wanted zend framework to handle the vanity urls. I looked at adding rules to the router to take care of this but again I didn&#8217;t feel like this would be the best approach plus I would still have the same issue of which is a valid vanity name versus a valid controller name. What I do know is that zend at some point knows if the requested url leads to a valid controller since it throws an exception otherwise. So the search began to find that piece of code.</p>
<p>I reread the basics on <a href="http://framework.zend.com/manual/en/zend.controller.basics.html">zend controller</a> to see where the code I&#8217;m looking for should be. Based on this image:</p>
<p style="text-align: center;"><img class="aligncenter" src="http://framework.zend.com/manual/en/figures/zend.controller.basics.png" alt="Zend Controller Diagram" /></p>
<p>You start with a request which is sent to the router and is then dispatched. Based on the <a href="http://framework.zend.com/manual/en/zend.controller.basics.html">framework documentation</a>, the <strong>Zend_Controller_Dispatcher_Interface</strong>:</p>
<blockquote><p>is used to define dispatchers. Dispatching is the process of pulling the controller and action from the request object and mapping them to a controller file (or class) and action method in the controller class. If the controller or action do not exist, it handles determining default controllers and actions to dispatch</p></blockquote>
<h4>Working with the controller dispatcher</h4>
<p>So Zend_Controller_Dispatcher_Interface is what handles loading the controller class and takes action if the controller is not valid. This seems like the best place to add my vanity code. My thoughts are to add code to Zend_Controller_Dispatch_Interface so if a controller is not valid, before throwing an exception, it&#8217;ll check if the vanity url is valid. If so, it&#8217;ll redirect the user to the correct page instead of displaying the contents of the new page. I&#8217;m choosing to redirect since I don&#8217;t want to have problems with duplicate content in Google or other search engines. There are ways around it, but for now this works well for me.</p>
<p>After reading the docs on the <a href="http://framework.zend.com/manual/en/zend.controller.dispatcher.html">zend controller dispatcher</a>, this part caught my eyes:</p>
<blockquote><p>in most cases, however, you should simply extend the abstract class Zend_Controller_Dispatcher_Abstract, in which each of these have already been defined, or Zend_Controller_Dispatcher_Standard to modify functionality of the standard dispatcher.</p></blockquote>
<p>Zend_Controller_Dispatcher_Standard already extends Abstract and has all the current functionality. So what I want to do is create a new class that will extend Zend_Controller_Dispatcher_Standard and rewrite the method that loads the controller file. The method is dispatch:</p>
<blockquote><p>/**<br />
* Dispatch a request to a (module/)controller/action.<br />
*<br />
* @param  Zend_Controller_Request_Abstract $request<br />
* @param  Zend_Controller_Response_Abstract $response<br />
* @return Zend_Controller_Request_Abstract|boolean<br />
*/<br />
public function dispatch(<br />
Zend_Controller_Request_Abstract $request,<br />
Zend_Controller_Response_Abstract $response<br />
);</p></blockquote>
<h4>Extending the current dispatcher</h4>
<p>I created a new file in my library under my/controller/dispatcher/standard.php that extends Zend_Controller_Dispatcher_Standard. Then I copied the <em>dispatch </em>method from Zend_Controller_Dispatcher_Standard and pasted it into my newly created class. Now I have my new class with one method &#8211; <em>dispatch</em>. You can open the file in your zend library folder to see everything the dispatch method does but I&#8217;m only going to be modifying the first part:</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">isDispatchable</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$controller</span> = <span class="re0">$request</span>-&gt;<span class="me1">getControllerName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$this</span>-&gt;<span class="me1">getParam</span><span class="br0">&#40;</span><span class="st0">&#8216;useDefaultControllerAlways&#8217;</span><span class="br0">&#41;</span> &amp;&amp; !<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$controller</span><span class="br0">&#41;</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="kw1">require_once</span> <span class="st0">&#8216;Zend/Controller/Dispatcher/Exception.php&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Zend_Controller_Dispatcher_Exception<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="st0">&#8216;Invalid controller specified (&#8216;</span> . <span class="re0">$request</span>-&gt;<span class="me1">getControllerName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> . <span class="st0">&#8216;)&#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="re0">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDefaultControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</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; <span class="re0">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$className</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">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDefaultControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p><em>isDispatchable</em> checks to see if the controller from the request is valid. For example, if we call: http://www.joeyrivera.com/car, isDispatchable checks to see if <em>car </em>is a valid controller. If it&#8217;s valid, the class is loaded and eventually gets called. If it&#8217;s not valid, there is a check to see if the <em>dispatch </em>method should load the default controller. If so, it loads it else it throws an exception.</p>
<h4>Implementing the vanity code</h4>
<p>There are two ways to handle the vanity code at this point: 1 &#8211; set <em>useDefaultControllerAlways </em>to true so if an invalid controller is found, the default controller is called anyways and you can then let that controller decide what to do. I can think of pros and cons on doing it that way, cleaner code maybe but more repetitive code also. It seems as if I would be rewriting what this dispatch method already does. I choose the second way which is to just check if my vanity url is valid here. If so, redirect else continue with the exception.</p>
<p>Here&#8217;s my code:</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">isDispatchable</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$controller</span> = <span class="re0">$request</span>-&gt;<span class="me1">getControllerName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$this</span>-&gt;<span class="me1">getParam</span><span class="br0">&#40;</span><span class="st0">&#8216;useDefaultControllerAlways&#8217;</span><span class="br0">&#41;</span> &amp;&amp; !<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$controller</span><span class="br0">&#41;</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="co1">// before we assume it&#8217;s bad, check for a vanity name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$user</span> = <span class="kw2">new</span> My_Model_User<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$user</span>-&gt;<span class="me1">find</span><span class="br0">&#40;</span><span class="re0">$controller</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// check if valid user and redirect</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<a href="http://www.php.net/is_null"><span class="kw3">is_null</span></a><span class="br0">&#40;</span><span class="re0">$user</span>-&gt;<span class="me1">user_id</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; <a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span><span class="st0">&quot;Location:&quot;</span> . parent::<span class="me2">getFrontController</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;<span class="me1">getBaseUrl</span><span class="br0">&#40;</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="st0">&quot;/controller/action/user_id/{$user-&gt;user_id}/<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; first_name/{$user-&gt;first_name}/<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; last_name/{$user-&gt;last_name}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</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">require_once</span> <span class="st0">&#8216;Zend/Controller/Dispatcher/Exception.php&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Zend_Controller_Dispatcher_Exception<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="st0">&#8216;Invalid controller specified (&#8216;</span> . <span class="re0">$request</span>-&gt;<span class="me1">getControllerName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> . <span class="st0">&#8216;)&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDefaultControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</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; <span class="re0">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$className</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">$className</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDefaultControllerClass</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>If the controller is not valid, and <em>useDefaultControllerAlways</em> is not true, then I create a new instance of my user model and try to find an user with the vanity name passed using the variable <em>$controller</em> which is already set to <em>$request-&gt;getControllerName()</em>. The vanity name is a field stored in the database with the rest of the user information. If the user is found, I redirect to the users profile page else I just let the method call the exception as usual. I call <em>parent::getFrontController()</em> so I can use the <em>getBaseUrl()</em> method when rewriting the redirect url.</p>
<h4>Updating the bootstrap</h4>
<p>This is all for the <em>dispatch </em>method but we aren&#8217;t done yet. Now that we have our new class we need to tell the framework to use it. To do this we need to modify the <em>bootstrap </em>class. Here is the code I added to the top of my <em>bootstrap.php</em> file:</p>
<div class="dean_ch" style="white-space: wrap;">protected <span class="kw2">function</span> _initVanityName<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">bootstrap</span><span class="br0">&#40;</span><span class="st0">&#8216;FrontController&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Retrieve the front controller from the bootstrap registry</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$front</span> = <span class="re0">$this</span>-&gt;<span class="me1">getResource</span><span class="br0">&#40;</span><span class="st0">&#8216;FrontController&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dispatcher</span> = <span class="kw2">new</span> My_Controller_Dispatcher_Standard<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$dispatcher</span>-&gt;<span class="me1">setControllerDirectory</span><span class="br0">&#40;</span><span class="re0">$front</span>-&gt;<span class="me1">getDispatcher</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getControllerDirectory</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$front</span>-&gt;<span class="me1">setDispatcher</span><span class="br0">&#40;</span><span class="re0">$dispatcher</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$front</span>;<br />
<span class="br0">&#125;</span></div>
<p>The first line makes sure the front controller resource gets initialized. Then we retrieve it via the <em>getResource </em>method. Next we instantiate the new dispatcher My_Controller_Dispatcher_Standard we created and set the controller directory since this won&#8217;t work without it. Finally we set the new dispatcher in the front controller instance and we are done.</p>
<h4>End Result</h4>
<p>Now, our application can handle vanity urls. Instead of having to remember long, complex urls such as</p>
<p>http://www.somesocialsite.com/?user_id=1231231&amp;page=somepage</p>
<p>we can use smaller, more readable urls like</p>
<p>http://www.somesocialsite.com/joeyrivera</p>
<h4>Thoughts</h4>
<p>I&#8217;m still not completely satisfied with this implementation so I&#8217;m sure I&#8217;ll be tweaking it some but it&#8217;s doing what I need it to do. I&#8217;m trying to think of ways, probably using cache, so I don&#8217;t have to hit the database each time a vanity url or an invalid controller name is passed. My other concern of having my code in the <em>dispatch </em>method is what happens when that method gets updated in future zend framework releases? Then I&#8217;ll have to remember to go back and update the method while if this code was in a controller that wouldn&#8217;t be an issue.</p>
<p>What do you guys think? Where do you guys implement this code? Let me hear your thoughts and thanks for reading.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/implementing-vanity-urls-in-php-w-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Extract collections of similar objects from an array in php</title>
		<link>http://www.joeyrivera.com/2009/extra-collections-of-similar-objects-from-an-array-in-php/</link>
		<comments>http://www.joeyrivera.com/2009/extra-collections-of-similar-objects-from-an-array-in-php/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 18:18:03 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[object]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=423</guid>
		<description><![CDATA[A co-worker was working on some stuff dealing with creating collections of objects within an array so I decided to play around with the idea. Basically, you start with a big array filled of objects and the objective is to create smaller arrays of similar objects. In this case we want collections of person objects [...]]]></description>
			<content:encoded><![CDATA[<p>A co-worker was working on some stuff dealing with creating collections of objects within an array so I decided to play around with the idea. Basically, you start with a big array filled of objects and the objective is to create smaller arrays of similar objects. In this case we want collections of person objects who names are the same. Here is what I came up with:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span></p>
<p><span class="kw2">class</span> person<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="re0">$id</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="re0">$name</span> = <span class="st0">&#8221;</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">$id</span>, <span class="re0">$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;<span class="me1">id</span> = <span class="re0">$id</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">name</span> = <span class="re0">$name</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="re0">$persons</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 />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">1</span>, <span class="st0">&#8216;bob&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">2</span>, <span class="st0">&#8216;bob&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">3</span>, <span class="st0">&#8216;moses&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">4</span>, <span class="st0">&#8216;joey&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">5</span>, <span class="st0">&#8216;bob&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">6</span>, <span class="st0">&#8216;joey&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">7</span>, <span class="st0">&#8216;bob&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">8</span>, <span class="st0">&#8216;moses&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">9</span>, <span class="st0">&#8216;joey&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$persons</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="kw2">new</span> person<span class="br0">&#40;</span><span class="nu0">10</span>, <span class="st0">&#8216;joey&#8217;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$collections</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// loop until there are no person left in array</span><br />
<span class="kw1">while</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">$persons</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// new collection and insert first person from array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$collection</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; <span class="re0">$collection</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$persons</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// now remove person from array since already in collection</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_shift"><span class="kw3">array_shift</span></a><span class="br0">&#40;</span><span class="re0">$persons</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// loop through each person in array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$x</span> = <span class="nu0">0</span>; <span class="re0">$x</span> &lt; <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$persons</span><span class="br0">&#41;</span>; <span class="re0">$x</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="co1">// check if there is a match</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$persons</span><span class="br0">&#91;</span><span class="re0">$x</span><span class="br0">&#93;</span>-&gt;<span class="me1">name</span> == <span class="re0">$collection</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>-&gt;<span class="me1">name</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="co1">// add person to this collection</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$collection</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$persons</span><span class="br0">&#91;</span><span class="re0">$x</span><span class="br0">&#93;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// pop if last item</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="nu0">+1</span>-<a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$persons</span><span class="br0">&#41;</span> == <span class="nu0">0</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; <a href="http://www.php.net/array_splice"><span class="kw3">array_splice</span></a><span class="br0">&#40;</span><span class="re0">$persons</span>, <span class="re0">$x</span><span class="br0">&#41;</span>;<br />
&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="kw1">else</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; <a href="http://www.php.net/array_splice"><span class="kw3">array_splice</span></a><span class="br0">&#40;</span><span class="re0">$persons</span>, <span class="re0">$x</span>, <span class="re0">$x</span><span class="nu0">+1</span>-<a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$persons</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">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// move back since array position gets deleted, else will skip over next index</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$x</span>&#8211;;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$collections</span><span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="re0">$collection</span>;<br />
<span class="br0">&#125;</span></p>
<p>debug<span class="br0">&#40;</span><span class="re0">$collections</span><span class="br0">&#41;</span>;<br />
<span class="kw2">function</span> debug<span class="br0">&#40;</span><span class="re0">$o</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;pre&gt;&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$o</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;/pre&gt;&#8217;</span>;<br />
<span class="br0">&#125;</span></div>
<p>And the result is:</p>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/array"><span class="kw3">Array</span></a><br />
<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">Array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; bob<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; bob<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">5</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; bob<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">7</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; bob<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">Array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">3</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; moses<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">8</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; moses<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">Array</span></a><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">4</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; joey<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">6</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; joey<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">9</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; joey<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> =&gt; person Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>id<span class="br0">&#93;</span> =&gt; <span class="nu0">10</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>name<span class="br0">&#93;</span> =&gt; joey<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></p>
<p><span class="br0">&#41;</span></div>
<p>You start with 1 big array and end up with, in this case, 3 arrays of person whos names are &#8216;bob&#8217;, then &#8216;moses&#8217;, and finally &#8216;joey&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/extra-collections-of-similar-objects-from-an-array-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
