<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Joey Rivera &#187; PHP</title>
	<atom:link href="http://www.joeyrivera.com/category/categories/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.joeyrivera.com</link>
	<description>Blogging about PHP, Actionscript, MySQL, and other interests.</description>
	<lastBuildDate>Fri, 02 Dec 2011 03:55:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Zend_Json_Server and how to call it via JSON-RPC 2.0</title>
		<link>http://www.joeyrivera.com/2011/zend_json_server-and-how-to-call-it-via-json-rpc-2-0/</link>
		<comments>http://www.joeyrivera.com/2011/zend_json_server-and-how-to-call-it-via-json-rpc-2-0/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 22:32:04 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[2.0]]></category>
		<category><![CDATA[json-rpc]]></category>
		<category><![CDATA[jsonrpc]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_json_server]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=656</guid>
		<description><![CDATA[So I started playing with Zend_Json_Server and was having a hard time trying to figure out how to call the server from a client. Finally I checked the JSON-RPC 2.0 spec and read a very important detail that I had not realized: The Request is expressed as a single JSON Object This was the key [...]]]></description>
			<content:encoded><![CDATA[<p>So I started playing with <a title="Zend_Json_Server docs" href="http://framework.zend.com/manual/en/zend.json.server.html">Zend_Json_Server</a> and was having a hard time trying to figure out how to call the server from a client. Finally I checked the <a title="Json-Rpc 2.0 specs" href="http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal?pli=1#request-procedure-call">JSON-RPC 2.0 spec</a> and read a very important detail that I had not realized:</p>
<blockquote><p>The Request is expressed as a single JSON Object</p></blockquote>
<p>This was the key to my problem. There are 4 parameters that can be sent with each JSON-RPC 2.0 request but I was sending each as a post var which is not what Zend_Json_Server expects. It simply wants one json encoded object with all the parameters inside. The 4 available parameters are:</p>
<ol>
<li>jsonrpc &#8211; the version you are using; I&#8217;m using 2.0.</li>
<li>method &#8211; the name of the method you want to call in the server.</li>
<li>params &#8211; object of parameters your method needs. If you don&#8217;t need any, don&#8217;t send this param.</li>
<li>id &#8211; an identifier (anything you want) that will be sent to and from the server for this request.</li>
</ol>
<p>I&#8217;m using Zend_Http_Client() to make the request and here is an example:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$params</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;jsonrpc&#8217;</span> =&gt; <span class="st0">&#8217;2.0&#8242;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;method&#8217;</span> =&gt; <span class="st0">&#8216;find&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;params&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8217;326691&#8242;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;id&#8217;</span> =&gt; <span class="st0">&#8216;test&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$http</span> = <span class="kw2">new</span> Zend_Http_Client<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$http</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://localhost/path/to/jsonrpc/server.php&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$http</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">POST</span><span class="br0">&#41;</span>;<br />
<span class="re0">$http</span>-&gt;<span class="me1">setRawData</span><span class="br0">&#40;</span>json_encode<span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$http</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p><span id="more-656"></span>And here is what I see in my browser when I make the call:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="br0">&#123;</span><br />
-result: <span class="br0">&#123;</span><br />
student_id: <span class="nu0">326691</span><br />
title: <span class="kw2">null</span><br />
first_name: <span class="st0">&quot;Accountbuilder&quot;</span><br />
last_name: <span class="st0">&quot;Random59&quot;</span><br />
middle_initial: <span class="st0">&quot;&quot;</span><br />
suffix: <span class="kw2">null</span><br />
address: <span class="st0">&quot;some place&quot;</span><br />
address2: <span class="kw2">null</span><br />
city: <span class="st0">&quot;Dallas&quot;</span><br />
-state: <span class="br0">&#123;</span><br />
state_id: <span class="nu0">11</span><br />
name: <span class="kw2">null</span><br />
abbr: <span class="kw2">null</span><br />
display_name: <span class="kw2">null</span><br />
sales_tax: <span class="nu0">0</span><br />
<span class="br0">&#125;</span><br />
zip: <span class="st0">&quot;30132&quot;</span><br />
phone: <span class="st0">&quot;111-111-1111&quot;</span><br />
fax: <span class="kw2">null</span><br />
username: <span class="kw2">null</span><br />
password: <span class="kw2">null</span><br />
<span class="br0">&#125;</span><br />
id: <span class="st0">&quot;test&quot;</span><br />
error: <span class="kw2">null</span><br />
jsonrpc: <span class="st0">&quot;2.0&quot;</span><br />
<span class="br0">&#125;</span></div>
<p>Basically, all I had to do was</p>
<ul>
<li>create an array of all the parameters I want to send on my request object. I&#8217;m calling the find method and passing an id</li>
<li>create a new client object</li>
<li>set the url to where your setting up your Zend_Json_Server</li>
<li>set the client to post (Zend_Json_Server only seems to handle post at this time)</li>
<li>json_encode your parameters array</li>
<li>pass the json_encoded object to the setRawData so it passes exactly what we want which is one json object to the server</li>
<li>call request to send the request and finally get body to show the response.</li>
</ul>
<p>Here is my code for the server.php file so you can see how I&#8217;m setting up the server:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$server</span> = <span class="kw2">new</span> Zend_Json_Server<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$server</span>-&gt;<span class="me1">setClass</span><span class="br0">&#40;</span><span class="st0">&#8216;Student&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$server</span>-&gt;<span class="me1">handle</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$response</span>;</div>
<p>I setup the server instance, add a class to handle the requests, call handle and echo the response. Student will look for the Student.php class so make sure it&#8217;s available in your include paths. That&#8217;s it, hope you found this helpful. As a side note, I noticed Zend_Amf_Server has a method to addDirectory instead of adding each class separately. Hopefully this gets added to Zend_Json_Server at some point.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2011/zend_json_server-and-how-to-call-it-via-json-rpc-2-0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Facebook Graph API App Easy w/ PHP SDK</title>
		<link>http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/</link>
		<comments>http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 20:14:56 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[sdk]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=642</guid>
		<description><![CDATA[NOTE: This post was written using Facebook&#8217;s PHP SDK version 2.1.2. Since this post was made, the PHP SDK has changed and some of the process that are explained below may have changed as well. At some point I&#8217;ll have to revisit this post and update it but at this time just keep in mind [...]]]></description>
			<content:encoded><![CDATA[<p>NOTE: This post was written using Facebook&#8217;s PHP SDK version 2.1.2. Since this post was made, the PHP SDK has changed and some of the process that are explained below may have changed as well. At some point I&#8217;ll have to revisit this post and update it but at this time just keep in mind of the above.</p>
<p>As promised, here is a post (similar to my Twitter API post) on using the Facebook API. There are many reason why one would want to access the Facebook API &#8211; maybe to create a mobile app that lets you post photos to your Facebook albums, or maybe you just want to show your last few Facebook status updates on your blog; what ever the reason may be, Facebooks Graph API mixed in with their PHP SDK makes it really easy to accomplish this.</p>
<h2>Objectives</h2>
<ul>
<li>Setup our environment</li>
<li>Register an app on Facebook</li>
<li>Understand the authentication process and extended parameters</li>
<li>Understand Graph API</li>
<li>Retrieve our latest status updates</li>
<li>Add a new status update</li>
<li>Retrieve our photos from our albums</li>
<li>Add a new photo<span id="more-642"></span></li>
</ul>
<h2>Setup our Environment</h2>
<p>You have two options here, you can access my github and download this project with all required files and library or you can follow this tutorial step by step &#8211; it&#8217;s really up to you. If you want to download all the files ahead of time, you can get them at this github <a title="github repo for this project" href="https://github.com/joeyrivera/Facebook-Graph-API-Examples" target="_blank">repo</a>. If you are going step by step, first create a folder (I&#8217;m calling mine facebook) in your server where you want this site, next create a folder named library in the root of this site, and finally add the following two files facebook.php and fb_ca_chain_bundle.crt in the library folder that you can get from the Facebook PHP SDK repo at: <a title="Facebook PHP SDK repo" href="https://github.com/facebook/php-sdk/tree/master/src/" target="_blank">https://github.com/facebook/php-sdk/tree/master/src/</a>.</p>
<h2>Register an App on Facebook</h2>
<p>I&#8217;m making the assumption you already have a facebook account and if you don&#8217;t, first create one. To create an app on Facebook, you first need to confirm your account by giving Facebook a phone number where they can send you a code. This may be a new process since I don&#8217;t remember having to do this a few months ago. Go to <a href="http://developers.facebook.com/setup">http://developers.facebook.com/setup</a> and if your account is not verified, you&#8217;ll be prompted to add the information mentioned above. After verifying your accout, you&#8217;ll be taken to the &#8216;Create an Application&#8217; page.</p>
<div class="wp-caption aligncenter" style="width: 355px"><img title="Create App" src="/blog_files/642/createapp.gif" alt="Create App" width="345" height="369" /><p class="wp-caption-text">This is what the page should look like</p></div>
<p>Simply give your site a name and type in your site&#8217;s url and click create app. In my case I&#8217;m calling my app &#8216;Blog Test&#8217; and my site would be &#8216;http://www.joeyrivera.com/&#8217;. Next you will be prompted to type in a captcha and continue. Now you are done setting up your app, you see a screen like the following with your app id and app secret:</p>
<div class="wp-caption aligncenter" style="width: 338px"><img title="App Created" src="/blog_files/642/appcreated.gif" alt="App Created" width="328" height="113" /><p class="wp-caption-text">Here is your app info</p></div>
<h2>Authenticating and Extended Parameters</h2>
<p>Facebook uses OAuth for authenticating involving tokens being send back and forth but we don&#8217;t have to concern ourselves with the details &#8211; the Facebook PHP SDK does it all for us. It makes sure to send all the required information in the proper format so Facebook gets what it needs and sends us back what we need. You can read more about authenticating with Facebook at their <a title="Facebook Authentication" href="http://developers.facebook.com/docs/authentication/">site</a> and you can also read my <a title="Joey Rivera Twitter API" href="http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/">Twitter API post</a> that discusses the OAuth in a little more detail if you are interested. The SDK also takes care of handling all API calls for us so we only have to give it the resource we are trying to access, let it know if we want to do a get or post, and finally give it all the parameters required for the call.</p>
<p>Extended Parameters is an interesting way of restricting access to an app (I&#8217;m using the term app to describe what we are building here) through the API. Unless a user allows access to certain parts of their account, an app will not be able to modify nor read parts of the account even if they are authenticated. Extended Parameters need to be explicitly assigned at the point of authenticating. When the user is taken to Facebook and asked to allow access to their account, the user is also presented with all the various parts of their account this app wants to interact with. Here is an example of what the user will see when trying to authenticate with our app:</p>
<div class="wp-caption aligncenter" style="width: 578px"><a href="All requested permissions"><img title="Extended Permissions" src="/blog_files/642/permissions.gif" alt="" width="568" height="410" /></a><p class="wp-caption-text">Extended Permissions</p></div>
<p>The first one in the screen shot is the default requested permission to access all the users basic information. The other three we need to accomplish our goals set including: read and post status updates as well as view and post photos. <a title="Facebook Extended Permissions" href="http://developers.facebook.com/docs/authentication/permissions">Here</a> you can see a complete list of all the available extended permissions. If you access that link, you&#8217;ll see there are a lot of permissions. I recommend taking some time reading through their descriptions to get a better understanding of the kinds of things you can do with the API. There have been times where I&#8217;ve tried to do something with an app and the Facebook Graph API without success only to find out I hadn&#8217;t requested a required permission for that to work.</p>
<p>Time for code, what we are about to do is to create an array with our app id and app secret to feed to the Facebook class when we instantiate it. Next, we are going to check to see if we are authenticated and if not, redirect us to the Facebook authenticate page passing it the extended parameters we want access to. Below is the code for the config.php file. Download form my <a title="Joey Rivera GitHub Repository" href="https://github.com/joeyrivera/Facebook-Graph-API-Examples">repository</a> or create the file below on the root of your site:</p>
<h4>config.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;library/facebook.php&#8217;</span>;</p>
<p><span class="re0">$app_id</span> = <span class="st0">&quot;yourappid&quot;</span>;<br />
<span class="re0">$app_secret</span> = <span class="st0">&quot;yourappsecret&quot;</span>;</p>
<p><span class="re0">$facebook</span> = <span class="kw2">new</span> Facebook<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; <span class="st0">&#8216;appId&#8217;</span> =&gt; <span class="re0">$app_id</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;secret&#8217;</span> =&gt; <span class="re0">$app_secret</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;cookie&#8217;</span> =&gt; <span class="kw2">true</span><br />
<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><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">$facebook</span>-&gt;<span class="me1">getUser</span><span class="br0">&#40;</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; &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:{$facebook-&gt;getLoginUrl(array(&#8216;req_perms&#8217; =&gt; &#8216;user_status,publish_stream,user_photos&#8217;))}&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/exit"><span class="kw3">exit</span></a>;<br />
<span class="br0">&#125;</span></div>
<p>Make sure to update the app_id and app_secret variables with the information you received from Facebook after registering your app. Let me give you a quick explanation of the code. First we include the facebook.php file that we downloaded from the Facebook PHP SDK github repository. Then we instantiate a facebook instance passing it the app id, app secret, and tell it to use cookies to store the session/token information after authenticating. Next we call getUser() to see if we are already authenticated &#8211; null means we are not, else we receive the users id. If we are not authenticated, we redirect the user to Facebook to authenticate. The url is provided to us from the getLoginUrl method. We are sending that method an array with a key req_perms (required permissions) and the value is a comma delimited list of all the extended permissions we want access to. Again, a complete list of all permissions can be found at <a title="Facebook Extended Permissiosn" href="http://developers.facebook.com/docs/authentication/permissions">Facebooks docs</a>.</p>
<p>Go ahead and try to access this page in your browser. You should be immediately redirected to Facebook. If you are not already logged in with your Facebook account, you&#8217;ll first be asked to log in with the user which you want your app to access. Next you&#8217;ll see the &#8216;Request for Permission&#8217; page, click allow and you&#8217;ll be taken back to the config.php page on your server. This process takes you back to the page which initiated the authentication which was the config.php page. We have now successfully authenticated with Facebook.</p>
<p>In testing your app, you may decide you need more or less extended permissions. While you are authenticated with Facebook and have your token stored in a cookie, you won&#8217;t be able to re-authenticate using this code since you&#8217;ll be getting a User object back so you have a few options: You can close your browser, clear cookies, and authenticate again after modifying your code; You can force another echo or header redirect to the getLoginUrl() again with the new parameters; or you can log into your Facebook account (the user you authenticated), click on account on the top right, privacy settings, and in the bottom left you&#8217;ll see application and websites, click on edit your settings. Under applications you use, you should see your app listed, click on edit settings. Finally click on the &#8216;x&#8217; delete button to delete your app from the list. This will now remove your app from this users app list and won&#8217;t allow the app to access this account until the user authenticates again.</p>
<h2>Graph API</h2>
<p>This was confusing to me at first, specially since I keep rushing my project instead of taking my time to carefully look and read over the documents to truly understand what&#8217;s going on. Here is the <a title="Facebook Graph API Overview" href="http://developers.facebook.com/docs/api">Facebook Graph API overview</a> if you would like to read that first but I&#8217;ll try to summarize it here. Graph API allows you to call various resources all of which will be returned to you as JSON objects. You&#8217;ll have to spend some time at the <a title="Facebook Graph API References" href="http://developers.facebook.com/docs/reference/api/">Graph API References</a> page to understand the different objects available, parameters they have, and what the required extended permissions are to access them. I&#8217;ll try to explain connections in a sec.</p>
<p>Lets talk about the <a title="Facebook Graph API User" href="http://developers.facebook.com/docs/reference/api/user">User</a> object first. If you look at the reference page for user, you&#8217;ll see that to call the user object (the user who is authenticated by the app) you would call the graph api url with a &#8216;/me&#8217; at the end. If the call is made successfully, you&#8217;ll receive a JSON object with all the possible properties defined in the reference page (if they are set). Here is a quick example.</p>
<h4>user.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;config.php&#8217;</span>;<br />
<span class="re0">$me</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&#8216;/me&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/var_dump"><span class="kw3">var_dump</span></a><span class="br0">&#40;</span><span class="re0">$me</span><span class="br0">&#41;</span>;</div>
<p>If you run this code you get something like this:</p>
<div class="wp-caption aligncenter" style="width: 596px"><img title="User Object" src="/blog_files/642/user.gif" alt="User Object" width="586" height="379" /><p class="wp-caption-text">This is my user object and properties.</p></div>
<p>Once you have the object, you can access it&#8217;s properties or do what you need with it. Now I&#8217;ll try to explain connections. If you look at the user reference page again and scroll down, you&#8217;ll see a connections section. These are the objects you can get that belong to this user. To access those objects you would call the url /me/object you want. For example, if you want to get this users albums, you would call /me/albums and this would return an array of album objects but remember to meet the required permission. For your app to access /me/albums, you need the user_photos extended permission (which we set in our config.php file).</p>
<p>So a connection is just a bridge between one object an another. Another example would be lets say we do as we did above and get all the users albums. Now we want to see all the photos inside each album. If you look at the <a title="Facebook Graph API Album Object" href="http://developers.facebook.com/docs/reference/api/album">album</a> object, you&#8217;ll notice that under connections is photos which returns an array of photo objects. That is what we would call to get all the photos in that album for each album and you&#8217;ll see the code to do just this later on.</p>
<h2>Get Status Posts</h2>
<p>Create the following page and I&#8217;ll explain the code below.</p>
<h4>status.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;config.php&#8217;</span>;</p>
<p><span class="co1">// show statuses</span><br />
<span class="re0">$statuses</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&#8216;/me/statuses&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$statuses</span><span class="br0">&#91;</span><span class="st0">&#8216;data&#8217;</span><span class="br0">&#93;</span> <span class="kw1">as</span> <span class="re0">$status</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="re0">$status</span><span class="br0">&#91;</span><span class="st0">&quot;message&quot;</span><span class="br0">&#93;</span>, <span class="st0">&quot;&lt;br /&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></div>
<p>First include the config.php file we created earlier (you&#8217;ll include this in all the other pages as well). The api method is what we&#8217;ll be using every time we need to call a resource and it can take in three parameters: the resource, get/post (defaults to get), and params (if any). In this case we want to call the statuses connection in the <a title="Facebook Graph API User Object" href="http://developers.facebook.com/docs/reference/api/user">user</a> object which returns and array of status messages. After receiving the messages, we loop through each and echo them out. If you want to see all the properties of each status, just do a var_dump on each status. That&#8217;s it, now the next example.</p>
<h2>Add New Status</h2>
<p>Here we are doing something a bit different, we are publishing to Facebook and for more info you can look at the <a title="Facebook Graph API Overview" href="http://developers.facebook.com/docs/api">Facebook Graph API Overview</a> in the publishing section. We want to create a new post so lets look at the <a title="Facebook Graph API Post Object" href="http://developers.facebook.com/docs/reference/api/post">reference guide</a> for information on post and its properties. Scroll down to the publishing section and notice we need the publish_stream extended property and you can see all the different properties that this object supports. I&#8217;m personally a bit confused on what is considered a required property and what it not, is seems nothing is required but for this example we want to submit a post with a message.</p>
<h4>status_add.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;config.php&#8217;</span>;</p>
<p><span class="co1">// add a status message</span><br />
<span class="re0">$status</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&#8216;/me/feed&#8217;</span>, <span class="st0">&#8216;POST&#8217;</span>, <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;This post came from my app.&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/var_dump"><span class="kw3">var_dump</span></a><span class="br0">&#40;</span><span class="re0">$status</span><span class="br0">&#41;</span>;</div>
<p>This is all the code required to make a post! It&#8217;s that easy. We call the api method, tell it we want to call the /me/feed connection, set method to post, and finally pass an array with the properties we want to set &#8211; in this case just the message property. If you wanted to set other properties, you would have set them in that array such as &#8216;link&#8217; =&gt; &#8216;http://link.to.something&#8217;, etc. If the call is successfully, you&#8217;ll receive an id back which is the id for the new post you just created. Run this code and if all goes well, you should be able to go check our the users Facebook wall and see this latest post. I don&#8217;t think you can post the same message twice (unless I&#8217;m confusing Facebook with Twitter) so if you try it twice and it doesn&#8217;t work, that might be why.</p>
<h2>View Photos From Albums</h2>
<p>In this example, we want to get all the different albums for our user. Then we need to loop through each album and make a second call that will return all the photos for each album.</p>
<h4>photos.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;config.php&#8217;</span>;</p>
<p><span class="co1">// get albums</span><br />
<span class="re0">$albums</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&#8216;/me/albums&#8217;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$albums</span><span class="br0">&#91;</span><span class="st0">&#8216;data&#8217;</span><span class="br0">&#93;</span> <span class="kw1">as</span> <span class="re0">$album</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// get all photos for album</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$photos</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&quot;/{$album['id']}/photos&quot;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$photos</span><span class="br0">&#91;</span><span class="st0">&#8216;data&#8217;</span><span class="br0">&#93;</span> <span class="kw1">as</span> <span class="re0">$photo</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">&quot;&lt;img src=&#8217;{$photo['source']}&#8217; /&gt;&quot;</span>, <span class="st0">&quot;&lt;br /&gt;&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>Here we call the albums connection on user to get all the album objects. We loop through each and for each album get the album id to then call the <a title="Facebook Graph API Photo Object" href="http://developers.facebook.com/docs/reference/api/photo">photo</a> connection on the <a title="Facebook Graph API Album Object" href="http://developers.facebook.com/docs/reference/api/album">album</a> object. If this sounds confusing just let me know and I&#8217;ll try to explain this further. When I think of connections I think of joins in a db. It&#8217;s like saying I want to join the albums table for the user in the user table therefor retrieving all rows in ablum for a specific user.</p>
<h2>Add Photo</h2>
<p>In the interest of time and complexity, I&#8217;m just going to add a photo without specifying an album. By doing this, Facebook will automatically create a new album to add this photo to. Just know that you can specify an album to add photos directly too if needed.</p>
<h4>photos_add.php</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">require_once</span> <span class="st0">&#8216;config.php&#8217;</span>;</p>
<p><span class="re0">$img</span> = <a href="http://www.php.net/realpath"><span class="kw3">realpath</span></a><span class="br0">&#40;</span><span class="st0">&quot;C:<span class="es0">\\</span>path<span class="es0">\\</span>to<span class="es0">\\</span>file.jpg&quot;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// allow uploads</span><br />
<span class="re0">$facebook</span>-&gt;<span class="me1">setFileUploadSupport</span><span class="br0">&#40;</span><span class="st0">&quot;http://&quot;</span> . <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&#8216;SERVER_NAME&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// add a status message</span><br />
<span class="re0">$photo</span> = <span class="re0">$facebook</span>-&gt;<span class="me1">api</span><span class="br0">&#40;</span><span class="st0">&#8216;/me/photos&#8217;</span>, <span class="st0">&#8216;POST&#8217;</span>,<br />
&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; <span class="st0">&#8216;source&#8217;</span> =&gt; <span class="st0">&#8216;@&#8217;</span> . <span class="re0">$img</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;message&#8217;</span> =&gt; <span class="st0">&#8216;This photo came from my app.&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
<span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/var_dump"><span class="kw3">var_dump</span></a><span class="br0">&#40;</span><span class="re0">$photo</span><span class="br0">&#41;</span>;</div>
<p>I choose this example for people that want to understand how to post a file through a service like this. First lets start at the top. We need to specify the path to the image we want to upload so change that path to where you file resides. Usually this would be the tmp path for a photo just uploaded to your server via $_FILE. Next we need to tell facebook to allow uploading of a file. I didn&#8217;t investigate that method much other then the comments said to specify the server so I use SERVER_NAME to signify this server. Next we make the call. We are calling /me/photos since that&#8217;s what is specified in the <a title="Facebook Graph API Photos Object" href="http://developers.facebook.com/docs/reference/api/photo">photos reference page</a> under publishing. We are passing two parameters, message is the text that will show up with the image and source is the image we want to upload. Notice there is an @ before the path to the image. This is because we want to post the contents of the file and not pass a string to where the file is. Run this code and if all worked well, you&#8217;ll see this image and an new album in your users Facebook page.</p>
<h2>Conclusion</h2>
<p>If all went well, your users Facebook wall should look something like this:</p>
<div class="wp-caption aligncenter" style="width: 543px"><img title="Done" src="/blog_files/642/done.gif" alt="Done" width="533" height="430" /><p class="wp-caption-text">My test users Facebook wall</p></div>
<p>I hope that with this, you have a good understanding on how Facebook&#8217;s Graph API works. Start trying to call other objects and play with different extended permissions. The Facebook team did a great job in providing us with the PHP SDK to make this so extremely easy so thumbs up to them. If you have any question/comments, just post them below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/feed/</wfw:commentRss>
		<slash:comments>253</slash:comments>
		</item>
		<item>
		<title>Twitter API, OAuth Authentication, and Zend_Oauth Tutorial</title>
		<link>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/</link>
		<comments>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 20:52:03 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[zend_oauth]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=617</guid>
		<description><![CDATA[I recently had to work on a project that required me to interact with the Twitter API. I had done this before so I wasn&#8217;t expecting anything different until I remembered that Twitter had changed their API to start using OAuth for authentication. If you are not familiar with OAuth, it&#8217;s a secure way of [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to work on a project that required me to interact with the Twitter API. I had done this before so I wasn&#8217;t expecting anything different until I remembered that Twitter had changed their API to start using OAuth for authentication. If you are not familiar with OAuth, it&#8217;s a secure way of authenticating without requiring a user to submit their username and password to third-parties &#8211; you can read more about it at <a title="OAuth Website" href="http://oauth.net/">OAuth</a>. There are lots of resources online that talk about this in detail but I wasn&#8217;t able to find one that explained the entire process in a way that made sense. Hopefully this post will give you everything you need to get started with the Twitter API. I&#8217;m going to go through the steps required to make this work without using the entire zend framework.</p>
<h2>Objective</h2>
<p>This tutorial will go step-by-step in explaining how to create a small PHP application that can interact with the Twitter API. Our goal is to:</p>
<ul>
<li>Authenticate</li>
<li>Display our latest tweets</li>
<li>Post new tweets from PHP</li>
<li>Display the last few times our account was mentioned</li>
</ul>
<p>The only assumptions at this point (other than knowing PHP) is that you have a twitter account and the zend framework library <a title="Get the Zend Framework" href="http://framework.zend.com/download/latest">downloaded</a>. We won&#8217;t be using the entire framework, just some of the files as standalone modules.</p>
<h2>Registering An App</h2>
<p>The first step in being able to communicate with the Twitter API is to register an app in their system so you can receive all the necessary keys to authenticate with OAuth. Go to <a title="Twitter Developer" href="http://dev.twitter.com/">dev.twitter.com</a> and log in with your Twitter account. Now click on &#8216;register an app&#8217; (if that link is not visible then click on &#8216;your apps&#8217; on the top right and then click on &#8216;register an app&#8217; in the next page). These are the values I put in the form on the next page for my app. Feel free to follow along. I&#8217;ll explain the important inputs.</p>
<p><strong>Application:</strong> Joey&#8217;s Blog Example<br />
<strong>Description:</strong> Twitter PHP App<br />
<strong>Application Website:</strong> http://www.joeyrivera.com<br />
<strong>Organization:</strong> None<br />
<strong>Application Type:</strong> Browser<br />
<strong>Callback URL:</strong> http://www.joeyrivera.com/twitter/callback.php<br />
<strong>Default Access Type:</strong> Read &amp; Write<span id="more-617"></span></p>
<p>Most of the above are self-explanatory but let me explain callback since it&#8217;s an important one. Before we can talk to Twitter, we need to authenticate to get a token from Twitter. Once we have our token, we can start calling the API. During authentication, we are actually going to leave our application and go to Twitters website where the user will have to enter their twitter credentials. After the user allows our application and is done authenticating, Twitter will redirect the user back to our applications callback url. We haven&#8217;t created the file yet, but point back to a file called &#8216;callback.php&#8217; where you plan on putting this file. We will create this file later. (I mentioned users don&#8217;t have to give third-parties their user/pass but they still have to let Twitter know it&#8217;s ok for this app to access their account.)</p>
<p>Enter the captcha and register. At this point we have successfully registered our app that can now start communicating with the Twitter API.</p>
<h2>Authenticating</h2>
<p>To authenticate using Zend_Oauth we need to create a consumer object. The consumer needs an array with the following parameters:</p>
<ul>
<li>callbackUrl: Same as the one used during &#8216;registering an app&#8217;.</li>
<li>siteUrl: The url where the token request will take place. In this case: &#8216;http://twitter.com/oauth&#8217;.</li>
<li>consumerKey: This value is assigned to you after registering your app. To get this value, log into dev.twitter.com, go to your apps, and select the app you just created during &#8216;registering an app&#8217; above. All your keys/secret and info will be listed on that page.</li>
<li>consumerSecret: same steps as consumerKey.</li>
</ul>
<p>We are going to be using the code from <a href="http://framework.zend.com/manual/en/zend.oauth.introduction.html">zend docs</a> with a couple minor tweaks or additions. The code is below:</p>
<h4>authenticate.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/session_start"><span class="kw3">session_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</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;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$consumer</span> = <span class="kw2">new</span> Zend_Oauth_Consumer<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// fetch a request token</span><br />
<span class="re0">$token</span> = <span class="re0">$consumer</span>-&gt;<span class="me1">getRequestToken</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// persist the token to storage</span><br />
<span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/serialize"><span class="kw3">serialize</span></a><span class="br0">&#40;</span><span class="re0">$token</span><span class="br0">&#41;</span>;</p>
<p><span class="co1">// redirect the user</span><br />
<span class="re0">$consumer</span>-&gt;<span class="me1">redirect</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
<p>Create a file and paste the above code in there and save your file as authenticate.php. Go back and modify the values of the $config array to use your callbackUrl, siteUrl, consumerKey, and consumerSecret. Also make sure to modify the include path to include your library folder where the zend framework resides (I&#8217;m using the framework version 1.10.8 for these examples).</p>
<p>Quick explanation of the code. First we start our session since we&#8217;ll be using a session variable to track the request token needed to create the access token later. Then we create a consumer and create the request token. Finally we call redirect on the consumer which sends us to twitter feeding it all the necessary information in the proper format for us to then authenticate. There is lots of magic going on behind the scene and for a better understanding on how the token and signature works read the OAuth docs. I personally find it much easier to use Zend_Oauth instead.</p>
<p>Now lets create the callback file, code is below:</p>
<h4>callback.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/session_start"><span class="kw3">session_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</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;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$consumer</span> = <span class="kw2">new</span> Zend_Oauth_Consumer<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$_GET</span><span class="br0">&#41;</span> &amp;amp;&amp;amp; <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$token</span> = <span class="re0">$consumer</span>-&gt;<span class="me1">getAccessToken</span><span class="br0">&#40;</span><span class="re0">$_GET</span>, <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="co1">// Now that we have an Access Token, we can discard the Request Token</span><br />
&nbsp; &nbsp; <span class="re0">$_SESSION</span><span class="br0">&#91;</span><span class="st0">&#8216;TWITTER_REQUEST_TOKEN&#8217;</span><span class="br0">&#93;</span> = <span class="kw2">null</span>;<br />
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// Mistaken request? Some malfeasant trying something?</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Invalid callback request. Oops. Sorry.&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></p>
<p><span class="co1">// save token to file</span><br />
file_put_contents<span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span>, <a href="http://www.php.net/serialize"><span class="kw3">serialize</span></a><span class="br0">&#40;</span><span class="re0">$token</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
<p>Save this file as callback.php after modifying the $config variables and library path just like with authenticate.php. We are once again starting our session to be able to capture the &#8216;TWITTER_REQUEST_TOKEN&#8217; created in the previous step. Then we create the consumer again and check to make sure the session is there and that we received query string parameters from Twitter. If everything is as expected, we feed the consumer all the information and ask it for an access token. This is the token we need to track since it&#8217;s the token we need for any call our application makes to the Twitter API. Since we no longer need the request token, we can remove it from the session.</p>
<p>The last step is to save the token somewhere so we can reuse it and not have to authenticate again. Twitter&#8217;s access token does not expire (at least not now). This means, once we authenticate with Twitter, as long as we have our access token stored and accessible to us, our client will not have to authenticate again (assuming Twitter doesn&#8217;t change their mind later and adds an expiration to their tokens). For the purpose of this example, I&#8217;m storing this token in the file system. Another option is to store this value in the database, it&#8217;s really up to you where you want to put it. If you are saving it to the file system, make sure that file is writable by your application.</p>
<p>Both files are created so lets try it out. Go to your browser and access the authenticate.php file. When the page loads, you should be redirected to Twitter and asked to log in (unless you are already logged into Twitter). Enter your twitter account user/pass that you want to access and continue. Next you&#8217;ll be asked if you want to allow this application to access your account. Go ahead and click allow, then you&#8217;ll be taken to your callback.php url. At this point we have authorized, received our access token, and stored it. Now we are done with our first goal and ready for the good stuff.</p>
<h2>Using our Token</h2>
<p>Our next goal was to display our latest tweets so this will be our first example on how to use our token. Technically, this isn&#8217;t the best example as you don&#8217;t need to authenticate with Twitter to display public user tweets but you&#8217;ll still get to see how to make a call to the Twitter API using our token.</p>
<h4>show_tweets.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</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;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/user_timeline.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">GET</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;screen_name&#8217;</span>, <span class="st0">&#8216;joeyrivera&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;count&#8217;</span>, <span class="st0">&#8217;10&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$tweets</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$tweets</span> <span class="kw1">as</span> <span class="re0">$tweet</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="re0">$tweet</span>-&gt;<span class="me1">text</span>, <span class="st0">&quot;&lt;br&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></div>
<p>Paste the above code into a file called show_tweets.php and edit the configs yet again plus the library. At this point I&#8217;ll stop mentioning to edit the config and library &#8211; just remember to do the same with the next couple examples. First we get our token which we saved to a file during the callback phase. Then we create a client object, tell it what url to call, the method to use and pass two params to let the API know who&#8217;s tweets we want and how many tweets to return. Finally we tell the client to initiate the request and we display it when it comes back.</p>
<p>Where did I get the uri from? from Twitters docs page. Spend some time there learning all the different methods you can call and what the required parameters are. For <a title="User Timeline" href="http://dev.twitter.com/doc/get/statuses/user_timeline">user_timeline</a> (which is what we want to get our latest tweets) we need to call the uri used above. The last part, the .json at the end tells Twitter that we want a JSON encoded response back which is why we need to do a json_decode on the body to view it. You could have used .xml if you wanted an xml back instead. The docs for user_timeline also specify you need to do a get which is why we set it as a method and add the two get parameters. There are more parameters you can set if you like.</p>
<p>This is what I see when I run this page with my screen name:</p>
<pre>Flash, jQuery, and Php - what a pain you have all been to me today but I'm glad all is well again.
Put my car up on autotrader, check it out if you are in the market for a 2005 Subaru WRX STi or know someone who might: http://is.gd/g3tqv
someone owns a image rollover patent? http://arstechnica.com/tech-policy/news/2010/10/patent-troll-takes-over-the-web-can-it-be-stopped.ars
Microsoft has the best commercials! http://holykaw.alltop.com/microsoft-pokes-fun-at-smartphone-users-in-ne
Finally got oAuth working to post to Twitter from PHP.
Accidentally found this very cool video by RefinedData http://refineddata.com/products/refinedtraining/index.php
You guys have recommendations on course authoring tools like articulate/captivate that don't have a player. Just a place to create content?
Cool story on YouTube instant http://www.feross.org/youtube-instant-media-frenzy/ Congrats to Feross on the accomplishment.
After driving a Z06 Corvette, I have become a believer of American muscle. STi was fun but just doesn't compare to a Z06.
Been week since we paid for Adobe developer support license and we are still not closer to solving our problem. Hoping to make progress soon</pre>
<p>Now lets submit a tweet.</p>
<h4>submit_tweet.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</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;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/update.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">POST</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterPost</span><span class="br0">&#40;</span><span class="st0">&#8216;status&#8217;</span>, <span class="st0">&#8216;I hope to get my blog post on Twitter API with Zend_Oauth up in the next day.&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$data</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$data</span>-&gt;<span class="me1">text</span>;</div>
<p>The code is very similar. The resource we want to call this time is <a title="Statuses/Update" href="http://dev.twitter.com/doc/post/statuses/update">statuses/update</a>. It requires a post method so we use POST and setParameterPost instead of GET. The one required param is status &#8211; set that to the string you want to tweet and run this page. Now go check your tweeter account and you should have that status show up. Make sure the string you pass is 140 characters or less. Also, twitter won&#8217;t allow you to submit two identical statuses so if you are testing this code and it&#8217;s not working, make sure you are sending a unique string.</p>
<p>Finally we&#8217;ll create one last example that displays the last 5 mentions of our twitter account.</p>
<h4>mentioned_tweet.php</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/set_include_path"><span class="kw3">set_include_path</span></a><span class="br0">&#40;</span><span class="st0">&#8216;/path/to/zend/library/1.10.8&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">require</span> <span class="st0">&#8216;Zend/Oauth/Consumer.php&#8217;</span>;</p>
<p><span class="re0">$config</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;callbackUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://www.joeyrivera.com/twitter/callback.php&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;siteUrl&#8217;</span> =&gt; <span class="st0">&#8216;http://twitter.com/oauth&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerKey&#8217;</span> =&gt; <span class="st0">&#8216;ASD234ADF34ADSF&#8217;</span>,<br />
&nbsp; &nbsp; <span class="st0">&#8216;consumerSecret&#8217;</span> =&gt; <span class="st0">&#8217;24GH789JSDFGDFG345098DF09873SDFSD&#8217;</span><br />
<span class="br0">&#41;</span>;</p>
<p><span class="re0">$token</span> = <a href="http://www.php.net/unserialize"><span class="kw3">unserialize</span></a><span class="br0">&#40;</span><a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="st0">&#8216;token.txt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$client</span> = <span class="re0">$token</span>-&gt;<span class="me1">getHttpClient</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setUri</span><span class="br0">&#40;</span><span class="st0">&#8216;http://twitter.com/statuses/mentions.json&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span>Zend_Http_Client::<span class="me2">GET</span><span class="br0">&#41;</span>;<br />
<span class="re0">$client</span>-&gt;<span class="me1">setParameterGet</span><span class="br0">&#40;</span><span class="st0">&#8216;count&#8217;</span>, <span class="st0">&#8217;5&#8242;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$response</span> = <span class="re0">$client</span>-&gt;<span class="me1">request</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p><span class="re0">$tweets</span> = json_decode<span class="br0">&#40;</span><span class="re0">$response</span>-&gt;<span class="me1">getBody</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re0">$tweets</span> <span class="kw1">as</span> <span class="re0">$tweet</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="re0">$tweet</span>-&gt;<span class="me1">text</span>, <span class="st0">&quot;&lt;br&gt;&quot;</span>;<br />
<span class="br0">&#125;</span></div>
<p>The <a title="Mentions" href="http://dev.twitter.com/doc/get/statuses/mentions">mentions</a> resource uses GET and doesn&#8217;t require any parameter. I&#8217;m passing a count of 5 so you don&#8217;t get too much back. Here is what I see when I run this page:</p>
<pre>heads up! @mosesngone and @joeyrivera consuming Web Services Nov 4th @atlantaphp #atlantaphp http://meetu.ps/3Rbt</pre>
<h2>Conclusion</h2>
<p>Using Zend_Oauth it&#8217;s really easy to authenticate with OAuth and track your token. At that point calling the Twitter API is very simple. I want to thank the guys at Zend for making our lives so much easier with all these great modules. If you have any question feel free to ask. Hopefully you have all found this post very informative and helpful.</p>
<p>EDIT: Here is a similar post on using <a title="Joey Rivera Facebook Graph API and PHP SDK Post" href="http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/">Facebooks Graph API with their PHP SDK</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/feed/</wfw:commentRss>
		<slash:comments>31</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 &#8216;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 &#8216;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>
<p>EDIT: Created new post on <a title="Twitter API and OAuth" href="http://www.joeyrivera.com/2010/twitter-api-oauth-authentication-and-zend_oauth-tutorial/" target="_self">using Twitter API and OAuth</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2010/using-zend_paginator-with-twitter-api-and-zend_cache/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Caching using PHP/Zend_Cache and MySQL</title>
		<link>http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/</link>
		<comments>http://www.joeyrivera.com/2009/caching-using-phpzend_cache-and-mysql/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 19:25:06 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend_cache]]></category>
		<category><![CDATA[zend_cache_backend_file]]></category>
		<category><![CDATA[zend_cache_frontend_core]]></category>
		<category><![CDATA[zend_cache_frontend_page]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=443</guid>
		<description><![CDATA[I like the definition used in Wikipedia: &#8220;a cache is a temporary storage area where often accessed data can be stored for quick access&#8221;. The idea is to get &#8216;often accessed data&#8217; from a database and store it in memory (RAM or as a file in your local file system). This is because: it&#8217;s quicker for [...]]]></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">&#8216;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">&#8216;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>33</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&#038;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 [...]]]></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&#038;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&#038;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>2</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>
		<item>
		<title>SQLSTATE[HY000]: General error &#8211; using php/pdo mysql stored procedures (sp)</title>
		<link>http://www.joeyrivera.com/2009/sqlstatehy000-general-error-using-phppdo-mysql-stored-procedures-sp/</link>
		<comments>http://www.joeyrivera.com/2009/sqlstatehy000-general-error-using-phppdo-mysql-stored-procedures-sp/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 15:15:39 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[general error]]></category>
		<category><![CDATA[hy000]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[sp]]></category>
		<category><![CDATA[sqlstate]]></category>
		<category><![CDATA[stored procedures]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=414</guid>
		<description><![CDATA[I spent many hours last night trying to figure out why I was getting a fatal error: &#8217;SQLSTATE[HY000]: General error 0&#8242; in my code and finally figured it out but first my environment. I&#8217;m using Zend Server CE running php 5.3.0, zend framework 1.9.0 and mysql 5.1.32. I should have tested this bug without the zend [...]]]></description>
			<content:encoded><![CDATA[<p>I spent many hours last night trying to figure out why I was getting a fatal error: &#8217;SQLSTATE[HY000]: General error 0&#8242; in my code and finally figured it out but first my environment. I&#8217;m using Zend Server CE running php 5.3.0, zend framework 1.9.0 and mysql 5.1.32. I should have tested this bug without the zend framework to make sure it&#8217;s not specific to zf (I don&#8217;t think it is) but I&#8217;m feeling lazy so I&#8217;ll let someone else try it out.</p>
<p>My code works as follows. I have a php class that calls a stored procedure which will take in an id, return a record set (if found) and will also return 2 out variables. While it was returning a record set everything was working perfectly fine. When I tried passing an invalid id, nothing was being returned and my code would keep giving me the &#8216;SQLSTATE[HY000]: General error 0&#8242; (very helpful error indeed&#8230;).</p>
<p>The issue ended up being the way I had my stored procedure coded. I would first check to see if the id passed was valid, if so I would select the data else I would set my out vars to some value and do nothing else. For some reason, because I wasn&#8217;t returning a select, my code would blow up. In the mysql query browser, my stored procedure worked fine and my second select to get the out vars was working correctly. But php didn&#8217;t like it one bit. I tried forcing a select in my stored procedure in the invalid id section and then everything worked fine again. This sounds a bit confusing so here is the way I can replicate this.<span id="more-414"></span></p>
<p>Here is a sample stored procedure:</p>
<div class="dean_ch" style="white-space: wrap;">DELIMITER $$</p>
<p><span class="kw1">DROP PROCEDURE</span> IF <span class="kw1">EXISTS</span> `test` $$<br />
<span class="kw1">CREATE PROCEDURE</span> `test`<br />
<span class="br0">&#40;</span><br />
&nbsp; OUT counter <span class="kw2">INT</span><br />
<span class="br0">&#41;</span><br />
<span class="kw1">BEGIN</span><br />
&nbsp; <span class="kw1">SET</span> counter = <span class="nu0">5</span>;<br />
<span class="kw1">END</span> $$</p>
<p>DELIMITER ;</p></div>
<p>In mysql query browser this works just fine if I call test(@out); and then select @out I get 5. But in my php code this blows up when I run:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$query</span> = <span class="st0">&quot;CALL test(@out);&quot;</span>;<br />
<span class="re0">$data</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>-&gt;<span class="me1">fetchAll</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span>;</div>
<p>To fix this problem I just need to add a select statement to the stored procedure even if I don&#8217;t need that data. I add select &#8216;hi&#8217;; to the sp and then my code works:</p>
<div class="dean_ch" style="white-space: wrap;">DELIMITER $$</p>
<p><span class="kw1">DROP PROCEDURE</span> IF <span class="kw1">EXISTS</span> `test` $$<br />
<span class="kw1">CREATE PROCEDURE</span> `test`<br />
<span class="br0">&#40;</span><br />
&nbsp; OUT counter <span class="kw2">INT</span><br />
<span class="br0">&#41;</span><br />
<span class="kw1">BEGIN</span><br />
&nbsp; <span class="kw1">SELECT</span> <span class="st0">&#8216;hi&#8217;</span>;<br />
&nbsp; <span class="kw1">SET</span> counter = <span class="nu0">5</span>;<br />
<span class="kw1">END</span> $$</p>
<p>DELIMITER ;</p></div>
<p>The quick testing php code:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$query</span> = <span class="st0">&quot;CALL test(@out);&quot;</span>;<br />
<span class="re0">$data</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>-&gt;<span class="me1">fetchAll</span><span class="br0">&#40;</span><span class="re0">$query</span><span class="br0">&#41;</span>;<br />
<span class="re0">$data</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>-&gt;<span class="me1">fetchRow</span><span class="br0">&#40;</span><span class="st0">&#8216;select @out;&#8217;</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</div>
<p>Instead of the general error now I get Array ( [@out] =&gt; 5 ) which is what was excepted. Hope this is helpful to you guys. Now I know I have to modify my stored procedures to always have a select even if it&#8217;s empty. What I don&#8217;t know if it&#8217;s specific to my environment or not which I may do more tests later to find out. If you try this and don&#8217;t get my same error please post so we have a better idea of what causing this issue or if you know why do share.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/sqlstatehy000-general-error-using-phppdo-mysql-stored-procedures-sp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating RSVP in PHP/MySQL w/ Zend Framework</title>
		<link>http://www.joeyrivera.com/2009/creating-rsvp-in-phpmysql-w-zend-framework/</link>
		<comments>http://www.joeyrivera.com/2009/creating-rsvp-in-phpmysql-w-zend-framework/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 20:16:03 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[rsvp]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=402</guid>
		<description><![CDATA[This post is to share the php/zend framework code I used to create an rsvp for my wedding site. I&#8217;m not going into all the details since that would take too long ;p but all the code is available if you want to use it. This was created using the zend framework version 1.7. So [...]]]></description>
			<content:encoded><![CDATA[<p>This post is to share the php/zend framework code I used to create an rsvp for my wedding site. I&#8217;m not going into all the details since that would take too long ;p but all the code is available if you want to use it. This was created using the zend framework version 1.7.</p>
<p>So I&#8217;m getting married in two month and for our wedding my fiancee and I decided to create a website for our guests. The site includes information such as location, time, links to registries, maps, and a section to rsvp. The site was made by my fiancee in html and css. When she was done, I ported it over to zend framework and started creating the rsvp section which I&#8217;ll describe next. You can view the finished wedding site here:</p>
<div style="text-align: center;"><img title="RSVP Page" src="http://www.joeyrivera.com/blog_files/402/images/rsvp-big.jpg" alt="RSVP Page" width="397" height="328" /></div>
<p style="text-align: center;"><a href="http://www.joeyrivera.com/wedding">http://www.joeyrivera.com/wedding</a></p>
<p><span id="more-402"></span>The objectives of the rsvp are the following:</p>
<ul>
<li>Allow guest to enter their code
<ul>
<li>each invitation that goes out has a code in it specific to the &#8216;family&#8217;.</li>
</ul>
</li>
<li>Validate code from database and load information about that family
<ul>
<li>return the family name and how many seats they have available. Because of seating limitations, we only allow x amounts of seats per family. Ex: A friend could have 2 seats available in case they are coming with a guest.</li>
</ul>
</li>
<li>Let guest select if they attending, if so, select how many guests are coming with an optional comments field</li>
<li>Submit and save their rsvp in the database and email us with the details</li>
</ul>
<p>The database structure is very simple, only one table that looks like:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">DROP TABLE</span> IF <span class="kw1">EXISTS</span> `family`;<br />
<span class="kw1">CREATE TABLE</span>  `family` <span class="br0">&#40;</span><br />
`family_id` <span class="kw2">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw3">UNSIGNED</span> <span class="kw3">NOT NULL</span> <span class="kw3">AUTO_INCREMENT</span>,<br />
`alias` <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 />
`code` <span class="kw2">SMALLINT</span><span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span> <span class="kw3">UNSIGNED</span> <span class="kw3">NOT NULL</span> <span class="kw3">DEFAULT</span> <span class="st0">&#8217;0&#8242;</span>,<br />
`attending` <span class="kw2">TINYINT</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw3">DEFAULT</span> <span class="kw3">NULL</span>,<br />
`available_seats` <span class="kw2">TINYINT</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span> <span class="kw3">UNSIGNED</span> <span class="kw3">NOT NULL</span>,<br />
`confirmed_seats` <span class="kw2">TINYINT</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span> <span class="kw3">UNSIGNED</span> <span class="kw3">DEFAULT</span> <span class="kw3">NULL</span>,<br />
`comments` <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw3">DEFAULT</span> <span class="kw3">NULL</span>,<br />
`last_access` <span class="kw2">DATETIME</span> <span class="kw3">DEFAULT</span> <span class="kw3">NULL</span>,<br />
<span class="kw1">PRIMARY KEY</span>  <span class="br0">&#40;</span>`family_id`<span class="br0">&#41;</span>,<br />
<span class="kw3">UNIQUE</span> KEY `Index_2` <span class="kw1">USING</span> <span class="kw1">BTREE</span> <span class="br0">&#40;</span>`code`<span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=<span class="kw1">INNODB</span> <span class="kw3">AUTO_INCREMENT</span>=<span class="nu0">80</span> <span class="kw3">DEFAULT</span> <span class="kw3">CHARSET</span>=latin1;</div>
<p>The fields are:</p>
<ul>
<li><strong>Alias </strong>is the &#8216;description or name&#8217; for the family such as Ashley and Joey Rivera or The Rivera&#8217;s.</li>
<li><strong>Code </strong>is the unique code we send out with each invitation.</li>
<li><strong>Attending </strong>is a boolean that is updated when the guest rsvps.</li>
<li><strong>Available seats</strong> is the number we set to limit how many people can come from that family.</li>
<li><strong>Confirmed seats</strong> is the number the guest sets when rsvping.</li>
<li><strong>Comments </strong>is optional</li>
<li><strong>Last access</strong> tracks the last time that row was updated</li>
</ul>
<p>I made code unique because it should be, we don&#8217;t want to accidentally assign two codes to the same family. We don&#8217;t want to use the family id as the code because we want the code a bit harder to guess if someone feels like fooling around with the system &#8211; we are hoping our family members and friends won&#8217;t purposely try to break the system though :p.</p>
<p>Here is the code:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw2">&lt;?php</span></p>
<p><span class="kw2">class</span> RsvpController <span class="kw2">extends</span> Zend_Controller_Action<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; protected <span class="re0">$_redirector</span> = <span class="kw2">null</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> init<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">$this</span>-&gt;_redirector = <span class="re0">$this</span>-&gt;_helper-&gt;<span class="me1">getHelper</span><span class="br0">&#40;</span><span class="st0">&#8216;Redirector&#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> indexAction<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">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">form</span> = <span class="re0">$this</span>-&gt;<span class="me1">rsvpForm</span><span class="br0">&#40;</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> submit1Action<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="co1">// get and filter code</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$filters</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;*&#8217;</span> =&gt; <span class="st0">&#8216;StringTrim&#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="re0">$validators</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;Digits&#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="re0">$input</span> = <span class="kw2">new</span> Zend_Filter_Input<span class="br0">&#40;</span><span class="re0">$filters</span>, <span class="re0">$validators</span>, <span class="re0">$this</span>-&gt;<span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getParams</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="co1">// verify code was passed</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$input</span>-&gt;<span class="me1">isValid</span><span class="br0">&#40;</span><span class="st0">&#8216;code&#8217;</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="co1">// go back with error message</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_redirect<span class="br0">&#40;</span><span class="st0">&#8216;/rsvp&#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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$code</span> = <span class="re0">$input</span>-&gt;<span class="me1">code</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// get family from code</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$family</span> = <span class="kw2">new</span> Family<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$family_row</span> = <span class="re0">$family</span>-&gt;<span class="me1">fetchRow</span><span class="br0">&#40;</span><span class="st0">&#8216;code = &#8216;</span> . <span class="re0">$code</span> . <span class="st0">&#8221;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if family doesn&#8217;t exist, leave</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/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$family_row</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">$this</span>-&gt;_redirect<span class="br0">&#40;</span><span class="st0">&#8216;/rsvp&#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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// track row in session</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span> = <span class="kw2">new</span> Zend_Session_Namespace<span class="br0">&#40;</span><span class="st0">&#8216;family&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span>-&gt;<span class="me1">code</span> = <span class="re0">$code</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span>-&gt;<span class="me1">row</span> = <span class="re0">$family_row</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// all is good, give view data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">family</span> = <span class="re0">$family_row</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">form</span> = <span class="re0">$this</span>-&gt;<span class="me1">familyForm</span><span class="br0">&#40;</span><span class="re0">$family_row</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> submit2Action<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="co1">// validate session</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span> = <span class="kw2">new</span> Zend_Session_Namespace<span class="br0">&#40;</span><span class="st0">&#8216;family&#8217;</span><span class="br0">&#41;</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/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$session</span>-&gt;<span class="me1">row</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">$this</span>-&gt;_redirect<span class="br0">&#40;</span><span class="st0">&#8216;/&#8217;</span><span class="br0">&#41;</span>;<br />
&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; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span> = <span class="re0">$this</span>-&gt;<span class="me1">familyForm</span><span class="br0">&#40;</span><span class="re0">$session</span>-&gt;<span class="me1">row</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// get vars to check</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$attending</span> = <span class="re0">$this</span>-&gt;<span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getParam</span><span class="br0">&#40;</span><span class="st0">&#8216;attending&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$seats</span> = <span class="re0">$this</span>-&gt;<span class="me1">getRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">getParam</span><span class="br0">&#40;</span><span class="st0">&#8216;seats&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// make sure data is good</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if attending but seats is 0 then ask them to select how many seats</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if the seats is greater than available seats error out</span><br />
&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">$attending</span> &amp;amp;&amp;amp; !<span class="re0">$seats</span><span class="br0">&#41;</span> || <span class="br0">&#40;</span><span class="re0">$attending</span> &gt; <span class="re0">$session</span>-&gt;<span class="me1">row</span>-&gt;<span class="me1">available_seats</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="co1">// assumed by passing error on element would trigger this but doesn&#8217;t seem too</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">markAsError</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="re0">$seats_element</span> = <span class="re0">$form</span>-&gt;<span class="me1">getElement</span><span class="br0">&#40;</span><span class="st0">&#8216;seats&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$seats_element</span>-&gt;<span class="me1">addError</span><span class="br0">&#40;</span><span class="st0">&#8216;Please select how many people are coming.&#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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//else if</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if not attending but selected seats, ask them about it</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>!<span class="re0">$attending</span> &amp;amp;&amp;amp; <span class="re0">$seats</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">$form</span>-&gt;<span class="me1">markAsError</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="re0">$attending_element</span> = <span class="re0">$form</span>-&gt;<span class="me1">getElement</span><span class="br0">&#40;</span><span class="st0">&#8216;attending&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$attending_element</span>-&gt;<span class="me1">addError</span><span class="br0">&#40;</span><span class="st0">&#8216;You selected you are not coming but set the number<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; of seat to a number greater than 0. Did you mean to say you are attending?&#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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if the form has an error, it can still be valid so need to check for both</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$form</span>-&gt;<span class="me1">isErrors</span><span class="br0">&#40;</span><span class="br0">&#41;</span> || !<span class="re0">$form</span>-&gt;<span class="me1">isValid</span><span class="br0">&#40;</span><span class="re0">$_POST</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">$form</span>-&gt;<span class="me1">populate</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#41;</span>; <span class="co1">// for some reason have to manually call this or values don&#8217;t show</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">form</span> = <span class="re0">$form</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">view</span>-&gt;<span class="me1">family</span> = <span class="re0">$session</span>-&gt;<span class="me1">row</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&#8216;index&#8217;</span><span class="br0">&#41;</span>;<br />
&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; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// update family</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$family</span> = <span class="kw2">new</span> Family<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$family</span>-&gt;<span class="me1">update</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;attending&#8217;</span> =&gt; <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;attending&#8217;</span><span class="br0">&#41;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;confirmed_seats&#8217;</span> =&gt; <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;seats&#8217;</span><span class="br0">&#41;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;comments&#8217;</span> =&gt; <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;comments&#8217;</span><span class="br0">&#41;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;last_access&#8217;</span> =&gt; <a href="http://www.php.net/date"><span class="kw3">date</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Y-m-d H:i:s&#8217;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>, <span class="st0">&#8216;code = &#8216;</span> . <span class="re0">$session</span>-&gt;<span class="me1">code</span> . <span class="st0">&#8221;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// email</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span> = <span class="kw2">new</span> Zend_Mail<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">setBodyText</span><span class="br0">&#40;</span><span class="st0">&#8216;New RSVP submitted.&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">setBodyHtml</span><span class="br0">&#40;</span><span class="st0">&#8216;&lt;p&gt;New RSVP submitted:&lt;/p&gt;<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; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;&#8217;</span> . <span class="re0">$session</span>-&gt;<span class="me1">row</span>-&gt;<span class="me1">alias</span> . <span class="st0">&#8216;&lt;/p&gt;<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; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Attending: &#8216;</span> . <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;attending&#8217;</span><span class="br0">&#41;</span> . <span class="st0">&#8216;&lt;/p&gt;<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; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Seats: &#8216;</span> . <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;seats&#8217;</span><span class="br0">&#41;</span> . <span class="st0">&#8216;&lt;/p&gt;<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; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Comments: &#8216;</span> . <span class="re0">$form</span>-&gt;<span class="me1">getValue</span><span class="br0">&#40;</span><span class="st0">&#8216;comments&#8217;</span><span class="br0">&#41;</span> . <span class="st0">&#8216; &lt;/p&gt;&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">setFrom</span><span class="br0">&#40;</span><span class="st0">&#8216;joey@joeyrivera.com&#8217;</span>, <span class="st0">&#8216;JoeyRivera.com&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">addTo</span><span class="br0">&#40;</span><span class="st0">&#8216;joey1.rivera@gmail.com&#8217;</span>, <span class="st0">&#8216;Joey Rivera&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">addTo</span><span class="br0">&#40;</span><span class="st0">&#8216;person@person.com&#8217;</span>, <span class="st0">&#8216;Ashley Fleishel&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">setSubject</span><span class="br0">&#40;</span><span class="st0">&#8216;Wedding New RSVP&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$mail</span>-&gt;<span class="me1">send</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_redirect<span class="br0">&#40;</span><span class="st0">&#8216;/rsvp/done&#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> doneAction<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="co1">// unset session</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span> = <span class="kw2">new</span> Zend_Session_Namespace<span class="br0">&#40;</span><span class="st0">&#8216;family&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$session</span>-&gt;<span class="me1">unsetAll</span><span class="br0">&#40;</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">private</span> <span class="kw2">function</span> rsvpForm<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">$form</span> = <span class="kw2">new</span> Zend_Form<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">setAction</span><span class="br0">&#40;</span><span class="st0">&#8216;/rsvp/submit1&#8242;</span><span class="br0">&#41;</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span><span class="st0">&#8216;post&#8217;</span><span class="br0">&#41;</span>-&gt;<span class="me1">setAttrib</span><span class="br0">&#40;</span><span class="st0">&#8216;id&#8217;</span>, <span class="st0">&#8216;rsvp&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;text&#8217;</span>, <span class="st0">&#8216;code&#8217;</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;label&#8217;</span> =&gt; <span class="st0">&#8216;RSVP Code (found on your invitation)&#8217;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;validators&#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;digits&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span> , <span class="st0">&#8216;required&#8217;</span> =&gt; <span class="kw2">true</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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;submit&#8217;</span>, <span class="st0">&#8216;submit&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$form</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">private</span> <span class="kw2">function</span> familyForm<span class="br0">&#40;</span><span class="re0">$family</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">$form</span> = <span class="kw2">new</span> Zend_Form<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">setAction</span><span class="br0">&#40;</span><span class="st0">&#8216;/rsvp/submit2&#8242;</span><span class="br0">&#41;</span>-&gt;<span class="me1">setMethod</span><span class="br0">&#40;</span><span class="st0">&#8216;post&#8217;</span><span class="br0">&#41;</span>-&gt;<span class="me1">setAttrib</span><span class="br0">&#40;</span><span class="st0">&#8216;id&#8217;</span>, <span class="st0">&#8216;rsvp&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;radio&#8217;</span>, <span class="st0">&#8216;attending&#8217;</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;label&#8217;</span> =&gt; <span class="st0">&#8216;Are you attending?&#8217;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;multiOptions&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="nu0">1</span> =&gt; <span class="st0">&#8216;Yes&#8217;</span> , <span class="nu0">0</span> =&gt; <span class="st0">&#8216;No&#8217;</span><span class="br0">&#41;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;validators&#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;Digits&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span> , <span class="st0">&#8216;required&#8217;</span> =&gt; <span class="kw2">true</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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// create array of seats</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$seats</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; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$x</span> = <span class="nu0">0</span>, <span class="re0">$max</span> = <span class="re0">$family</span>-&gt;<span class="me1">available_seats</span>; <span class="re0">$x</span> &lt;= <span class="re0">$max</span>; <span class="re0">$x</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">$seats</span><span class="br0">&#91;</span><span class="re0">$x</span><span class="br0">&#93;</span> = <span class="re0">$x</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// limit number to available seats from row session</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;select&#8217;</span>, <span class="st0">&#8216;seats&#8217;</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;label&#8217;</span> =&gt; <span class="st0">&#8216;How many will be attending?&#8217;</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;multiOptions&#8217;</span> =&gt; <span class="re0">$seats</span> ,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;required&#8217;</span> =&gt; <span class="kw2">true</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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;textarea&#8217;</span>, <span class="st0">&#8216;comments&#8217;</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;label&#8217;</span> =&gt; <span class="st0">&#8216;Comments&#8217;</span> , <span class="co1">//&#8217;validators&#8217; =&gt; array(</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//&nbsp; &nbsp; &nbsp; &#8216;Alnum&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//),</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;required&#8217;</span> =&gt; <span class="kw2">false</span> , <span class="st0">&#8216;width&#8217;</span> =&gt; <span class="nu0">250</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; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$form</span>-&gt;<span class="me1">addElement</span><span class="br0">&#40;</span><span class="st0">&#8216;submit&#8217;</span>, <span class="st0">&#8216;submit&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$form</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
<p>I&#8217;ll summarize what I&#8217;m doing with the code. I have 4 actions in my RsvpController:</p>
<h4>index</h4>
<ul>
<li>This action display the rsvpForm in the view which is a input box for the guests to type in their family code.</li>
</ul>
<h4>submit1 (I know, name sucks but I was going for something quick ;p)</h4>
<ul>
<li>This action will validate the code submitted by the index action.</li>
<li>It then creates an instance of family using a zend db table model and loads the data from the database for the family that matches that code.</li>
<li>If it&#8217;s a real family, a session var is created with the family data and the form familyForm is displayed. Else, the user is taken back to the index action.</li>
</ul>
<h4>submit2</h4>
<ul>
<li>When the familyForm is submitted in submit1, this action validates that there is a family session var.</li>
<li>Then it does a few validations more such as making sure that the family seats is a number greater than 0 if they are attending. Or didn&#8217;t choose a number of seats greater than 0 if they are not attending (in case they accidentally hit not coming but did want to).</li>
<li>Then it validates the submitted form &#8211; I put it at the end because it seemed as if it would be less code that way. You can read the comments to see why I did what I did, I had some issues with the way I was expecting the form zend framework class to behave.</li>
<li>If all is well, the family row in the database is updated and an email is sent to myself and fiancee.</li>
</ul>
<h4>done</h4>
<ul>
<li>Displays a done message and the rsvp process is complete!</li>
</ul>
<p>That&#8217;s about it. A couple quick thoughts or comments about this. The form could be made more secure but like I said before, for this project I think it&#8217;s fine. Also, you&#8217;ll see a bunch of css in the views, it&#8217;s because I was trying to port the site over quickly and that was the quickest way. If you have any specific questions feel free to ask. Hope you find this useful. Below are some screen shots of the final product and a zip file of the code including the model, the rsvp controller, and the views in the application folder:</p>
<p><a href="http://www.joeyrivera.com/blog_files/402/application.zip">RSVP Files</a></p>
<p>index:</p>
<p><img class="alignnone" title="Index image" src="http://www.joeyrivera.com/blog_files/402/images/rsvp-index.jpg" alt="" width="289" height="178" /></p>
<p>submit1:</p>
<p><img class="alignnone" title="Options Image" src="http://www.joeyrivera.com/blog_files/402/images/rsvp-options.jpg" alt="" width="293" height="368" /></p>
<p>done:</p>
<p><img class="alignnone" title="Done Image" src="http://www.joeyrivera.com/blog_files/402/images/rsvp-done.jpg" alt="" width="285" height="122" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/creating-rsvp-in-phpmysql-w-zend-framework/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Using MySQL Stored Procedure IN/OUT and Recordset w/ PHP</title>
		<link>http://www.joeyrivera.com/2009/using-mysql-stored-procedure-inout-and-recordset-w-php/</link>
		<comments>http://www.joeyrivera.com/2009/using-mysql-stored-procedure-inout-and-recordset-w-php/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 03:21:29 +0000</pubDate>
		<dc:creator>Joey</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[sp]]></category>
		<category><![CDATA[stored procedures]]></category>

		<guid isPermaLink="false">http://www.joeyrivera.com/?p=395</guid>
		<description><![CDATA[Note: The code below will not work on all environments. I&#8217;m using php 5.2.6 with mysql driver 5.0.18. In a previous post: http://www.joeyrivera.com/2009/using-mysql-stored-procedures-with-php-mysqlmysqlipdo/ I explained how to use MySQL stored procedures with different db adapters such as mysql, mysqli, and pdo in PHP. In those examples, I demonstrated calling a sp with in/out variables and [...]]]></description>
			<content:encoded><![CDATA[<p>Note: The code below will not work on all environments. I&#8217;m using php 5.2.6 with mysql driver 5.0.18.</p>
<p>In a previous post:<br />
<a href="http://www.joeyrivera.com/2009/using-mysql-stored-procedures-with-php-mysqlmysqlipdo/">http://www.joeyrivera.com/2009/using-mysql-stored-procedures-with-php-mysqlmysqlipdo/</a></p>
<p>I explained how to use MySQL stored procedures with different db adapters such as mysql, mysqli, and pdo in PHP. In those examples, I demonstrated calling a sp with in/out variables and calling a stored procedure that returns a recordset. One of the comments I received was a person asking how to call a stored procedure that uses in/out parameters as well as returns a recordset. It&#8217;s not much different and here&#8217;s how.</p>
<p>The trick is to combine both methods in one. Here&#8217;s an example of what the stored procedure looks like:</p>
<div class="dean_ch" style="white-space: wrap;">DELIMITER $$<br />
<span class="kw1">DROP PROCEDURE</span> IF <span class="kw1">EXISTS</span> `test`.`get_users` $$<br />
<span class="kw1">CREATE PROCEDURE</span> `get_users`<span class="br0">&#40;</span><br />
<span class="kw5">IN</span> firstName <span class="kw2">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span>,<br />
OUT totalUsers <span class="kw2">INT</span><br />
<span class="br0">&#41;</span><br />
<span class="kw1">BEGIN</span><br />
<span class="kw1">SELECT</span> COUNT<span class="br0">&#40;</span>*<span class="br0">&#41;</span><br />
<span class="kw1">INTO</span> totalUsers<br />
<span class="kw1">FROM</span> users<br />
<span class="kw1">WHERE</span> first_name = firstName;<br />
<span class="kw1">SELECT</span> *<br />
<span class="kw1">FROM</span> users<br />
<span class="kw1">WHERE</span> first_name = firstName;<br />
<span class="kw1">END</span> $$<br />
DELIMITER ;</div>
<p><span id="more-395"></span>Notice there are two statements in the body of this stored procedure. The first select count(*) statement counts the total number of people who&#8217;s first name is equal to the in variable firstName. Once it&#8217;s gets the count, it sets the out variable totalUsers to that value.</p>
<p>The next statement is a simple select. This will select all fields for users who&#8217;s first name is equal to the in variable firstName and return the recordset. So by calling this stored procedure and passing in two parameters (first name, total), a recordset will be returned and an out variable will be set &#8211; that can then be queried.</p>
<p>I&#8217;m using the same users table from my previous post on stored procedures. Click on the link above to access that post and copy the create statement. I&#8217;m using a bit more data on the users table this time for this example to work. Here&#8217;s the insert statement:</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>The code is pretty simple, pretty much you want to do two queries. The first calls the stored procedure and passes in both variables. This first query will return a recordset (the second select statement in the body of the stored procedure. The next query will select totalUsers to get that variable and display it. Here&#8217;s the php code to do this in both mysql and pdo_mysql:</p>
<h4>MySQL</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$mysql</span> = <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;test&#8217;</span>, <span class="st0">&#8216;test&#8217;</span>, <span class="kw2">false</span>, <span class="nu0">65536</span><span class="br0">&#41;</span>;<br />
<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="re0">$mysql</span><span class="br0">&#41;</span>;<br />
<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="st0">&quot;call get_users(&#8216;joey&#8217;, @total);&quot;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$row</span> = <span class="br0">&#40;</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><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$row</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;br /&gt;&#8217;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="co1">// now get the @total var</span><br />
<span class="re0">$rs2</span> = <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st0">&quot;select @total;&quot;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$total</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">$rs2</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$total</span><span class="br0">&#41;</span>;</div>
<h4>PDO</h4>
<div class="dean_ch" style="white-space: wrap;"><span class="re0">$pdo</span> = <span class="kw2">new</span> PDO<span class="br0">&#40;</span><span class="st0">&#8216;mysql:dbname=test;host=127.0.0.1&#8242;</span>, <span class="st0">&#8216;test&#8217;</span>, <span class="st0">&#8216;test&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="re0">$data</span> = <span class="re0">$pdo</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">&quot;call get_users(&#8216;joey&#8217;, @totalUsers);&quot;</span><span class="br0">&#41;</span>-&gt;<span class="me1">fetchAll</span><span class="br0">&#40;</span>PDO::<span class="me2">FETCH_ASSOC</span><span class="br0">&#41;</span>;<br />
<span class="re0">$total_count</span> = <span class="re0">$pdo</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">&quot;select @totalUsers;&quot;</span><span class="br0">&#41;</span>-&gt;<span class="me1">fetchAll</span><span class="br0">&#40;</span>PDO::<span class="me2">FETCH_ASSOC</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&#8216;&lt;br /&gt;&#8217;</span>;<br />
<a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$total_count</span><span class="br0">&#41;</span>;</div>
<p>This code should output:</p>
<h4>MySQL</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">6</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Rivera <span class="br0">&#41;</span><br />
<a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">8</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Tester <span class="br0">&#41;</span><br />
<a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">9</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Test <span class="br0">&#41;</span><br />
<a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <span class="br0">&#91;</span>@total<span class="br0">&#93;</span> =&gt; <span class="nu0">3</span> <span class="br0">&#41;</span></div>
<h4>PDO</h4>
<div class="dean_ch" style="white-space: wrap;"><a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <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> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">6</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Rivera <span class="br0">&#41;</span> <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> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">8</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Tester <span class="br0">&#41;</span> <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> <span class="br0">&#40;</span> <span class="br0">&#91;</span>users_id<span class="br0">&#93;</span> =&gt; <span class="nu0">9</span> <span class="br0">&#91;</span>first_name<span class="br0">&#93;</span> =&gt; Joey <span class="br0">&#91;</span>last_name<span class="br0">&#93;</span> =&gt; Test <span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
<a href="http://www.php.net/array"><span class="kw3">Array</span></a> <span class="br0">&#40;</span> <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> <span class="br0">&#40;</span> <span class="br0">&#91;</span>@totalUsers<span class="br0">&#93;</span> =&gt; <span class="nu0">3</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
<p>Like I mentioned before, both sets of code are doing the same thing, calling two queries. First the stored procedure (passing in joey for firstname and @total as the out var) then query for the out variable @total. I took a few shortcuts with pdo so it seems like less code. I personally like pdo better and it&#8217;s what I use on my projects. I hope you all find this helpful and feel free to ask any question or post any comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joeyrivera.com/2009/using-mysql-stored-procedure-inout-and-recordset-w-php/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>

