<?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>Adam Gotterer &#187; Programming</title>
	<atom:link href="http://www.adamgotterer.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adamgotterer.com</link>
	<description>Find the secrets to infinite income, and automate it!</description>
	<lastBuildDate>Wed, 21 Jul 2010 02:44:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building an Object Collection Manager with the Standard PHP Library (SPL)</title>
		<link>http://www.adamgotterer.com/2009/10/23/building-a-php-object-collection-manager-with-spl/</link>
		<comments>http://www.adamgotterer.com/2009/10/23/building-a-php-object-collection-manager-with-spl/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 14:00:59 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Standard PHP Library]]></category>
		<category><![CDATA[ArrayAccess]]></category>
		<category><![CDATA[Collection]]></category>
		<category><![CDATA[Countable]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/?p=165</guid>
		<description><![CDATA[Introduction
The purpose of a collection is to store objects in an organized manner with specific access rules. We are going to build a collection class using the Standard PHP Library (SPL). Our final product will be capable of iterating, counting and access to objects via array. If you are not familiar with SPL you can [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>The purpose of a collection is to store objects in an organized manner with specific access rules. We are going to build a collection class using the Standard PHP Library (SPL). Our final product will be capable of iterating, counting and access to objects via array. If you are not familiar with SPL you can find some additional information on the <a href="http://php.net/manual/en/book.spl.php">PHP SPL manual</a> site. Unfortunately the manual is somewhat lacking. Here is a more detailed list of <a href="http://www.php.net/~helly/php/ext/spl/">SPL classes</a>.</p>
<p>We will call our class &#8220;Collection&#8221; (original, I know). This class will eventually implement the SPL classes: ArrayAccess, Countable and Iterator. If you are unfamiliar with SPL your first reaction may be that you don&#8217;t have any of these classes in your project. The beauty of SPL is that the classes are built into PHP (compiled by default). Once you implement a class you are exposed to a series of abstract function which you must implement. Once implemented the result is the ability to manipulate objects and create functionality you wouldn&#8217;t normally be able to code.</p>
<p>First we are going to do a quick introduction to the interfaces we will be using. After that we will jump right into code and examples. Please keep in mind that the collection class we are going to build is more about demonstrating the capabilities of these particular SPL interfaces then actual practical use, although you could easily turn this into a useful class.</p>
<p><strong>ArrayAccess</strong><br />
ArrayAccess is an interface that lets you override array access of objects. Basically it lets you use an object as an array and use keys to access values stored within the class.<br />
<br />
<span style="text-decoration: underline;">Abstract Functions</span></p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">offsetExists($offset)<br />
offsetGet($offset)<br />
offsetSet($offset, $value)<br />
offsetUnset($offset)</div></div>
</pre>
<p></p>
<p><strong>Countable</strong><br />
Countable lets you hook into the global count function and override it. We are going to use it to count the number of objects in our collection.<br />
<br />
<span style="text-decoration: underline;">Abstract Functions</span></p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">count()</div></div>
</pre>
<p></p>
<p><strong>Iterator</strong><br />
Iterator allows you to iterator over an object. In our example you will be able to directly loop over a collection and return the objects that are stored.<br />
<br />
<span style="text-decoration: underline;">Abstract Functions</span></p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">current()<br />
key()<br />
next()<br />
rewind()<br />
valid()</div></div>
</pre>
<h2>Implementation</h2>
<p>The first thing we need to do is define our class. It should look something like this:</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #000000; font-weight: bold;">class</span> collection <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
</pre>
<p></p>
<p>Next we will define a constructor and a private variable called $object that will store the objects we pass into this collection. The constructor will be one way to populate the collection.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> collection <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$objects</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p></p>
<p>At this point our class doesn&#8217;t do much but take an array of objects and store then in the class. Next we will implement the SPL classes we discussed earlier.</p>
<p><strong>Implement ArrayAccess</strong></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> collection implements ArrayAccess <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL ArrayAcess **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetExists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetSet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetUnset<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End ArrayAccess Abstraction</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p></p>
<p><strong>Implement Countable</strong><br />
Countable is really simple to implement and only requires one function. There is an interesting note in the code comment that you should make note of.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> collection implements ArrayAccess<span style="color: #339933;">,</span> Countable <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL ArrayAcess **/</span><br />
&nbsp; &nbsp; <span style="color: #339933;">...</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End ArrayAccess Abstraction</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL Countable **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Note from PHP manual: If var is not an array or an object with </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// implemented Countable interface, 1 will be returned.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Not sure why it returns one, but we need to make sure our </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// count is right and returns zero when there are no objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End Countable Abstraction</span></div></div>
</pre>
<p></p>
<p><strong>Implement Iterator</strong></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> collection implements ArrayAccess<span style="color: #339933;">,</span> Countable<span style="color: #339933;">,</span> Iterator <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL ArrayAcess **/</span><br />
&nbsp; &nbsp; <span style="color: #339933;">...</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End ArrayAccess Abstraction</span><br />
<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL Countable **/</span><br />
&nbsp; &nbsp; <span style="color: #339933;">...</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End Countable Abstraction</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL Iterator **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">key</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">key</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">rewind</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> valid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// END Iterator Abstraction</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<h2>Final Collection</h2>
<p>Our completed class isnt all that complicated. But its extremely powerful if used the right way. Hopefully you were able to follow along and understand what we have built. The final code is posted below as well as a test case in the next section. I recommend running the test to really see what the class is capable of doing.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> collection implements ArrayAccess<span style="color: #339933;">,</span> Countable<span style="color: #339933;">,</span> Iterator <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$objects</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL ArrayAcess **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetExists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetSet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> final <span style="color: #000000; font-weight: bold;">function</span> offsetUnset<span style="color: #009900;">&#40;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$offset</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End ArrayAccess Abstraction</span><br />
<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL Countable **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Note from PHP manual: If var is not an array or an object with </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// implemented Countable interface, 1 will be returned.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Not sure why it returns one, but we need to make sure our </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// count is right and returns zero when there are no objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// End Countable Abstraction</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009933; font-style: italic;">/** ABSTRACT SPL Iterator **/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">key</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">key</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">rewind</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> valid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">objects</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// END Iterator Abstraction</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
</pre>
<p></p>
<h2>Testing and Demonstration</h2>
<p><strong>Test Code</strong></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #009933; font-style: italic;">/** FOO CLASS USED TO POPULATE OUR TEST COLLECTION */</span><br />
<span style="color: #000000; font-weight: bold;">class</span> Foo <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<br />
<span style="color: #009933; font-style: italic;">/** DEMONSTRATION **/</span><br />
<span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$x</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span> <span style="color: #000088;">$x</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$objects</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Foo<span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000088;">$collection</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Collection<span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// offsetExists</span><br />
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span>3<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 3 exists<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 3 doesnt exist<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// offsetGet</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Value of offset 1: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// offsetSet</span><br />
<span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span>3<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Foo<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'A'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 3 has been changed, the object value is now: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// offsetUnset</span><br />
<span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span>2<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 2 has been removed. &quot;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$collection</span><span style="color: #009900;">&#91;</span>2<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 2 exists<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Offset 2 doesnt exist<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<br />
<span style="color: #666666; font-style: italic;">// Countable</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;This collection has &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$collection</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; objects<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<br />
<br />
<span style="color: #666666; font-style: italic;">// Iterating</span><br />
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Looping through our collection:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$collection</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$object</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Index &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; = &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></div>
</pre>
<p><strong>Test Output</strong></p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Offset 3 exists<br />
Value of offset 1: 1<br />
Offset 3 has been changed, the object value is now: A<br />
Offset 2 has been removed. Offset 2 doesnt exist<br />
<br />
This collection has 4 objects<br />
<br />
Looping through our collection:<br />
Index 0 = 0<br />
Index 1 = 1<br />
Index 3 = A<br />
Index 4 = 4</div></div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2009/10/23/building-a-php-object-collection-manager-with-spl/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Forcing files to download from Amazon S3</title>
		<link>http://www.adamgotterer.com/2009/09/23/forcing-files-to-download-from-amazon-s3/</link>
		<comments>http://www.adamgotterer.com/2009/09/23/forcing-files-to-download-from-amazon-s3/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 05:39:11 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[S3]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2009/09/23/forcing-files-to-download-from-amazon-s3/</guid>
		<description><![CDATA[I have been messing around with Amazon S3 for hosting files the last few days. One of the things I wanted to do was force a file to download instead of the browser attempting to open it (jpgs, txt, mp3, etc.). A quick Google search didn&#8217;t return anything useful. There is a whole bunch of [...]]]></description>
			<content:encoded><![CDATA[<p>I have been messing around with Amazon S3 for hosting files the last few days. One of the things I wanted to do was force a file to download instead of the browser attempting to open it (jpgs, txt, mp3, etc.). A quick Google search didn&#8217;t return anything useful. There is a whole bunch of people trying to use PHP headers and read in the file from Amazon. This is a horrible idea. It requires your server to download the file first, then deliver it to the client. Double work, bad solution.</p>
<p>There is a much easier way&#8230; S3 allows you to set request headers on a per object basis. In order to force a file download dialog you just need to set the &#8220;Content-Disposition&#8221; header.</p>
<p>Here&#8217;s an example using the <a href="http://undesigned.org.za/2007/10/22/amazon-s3-php-class">Undesigned Amazon S3 PHP class</a> (highly recommended). This header should easily integrate into whatever system you are using to interact with the S3 API. If you need additional information take a look at the <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTObjectGET.html">S3 documentation</a>.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">S3<span style="color: #339933;">::</span><span style="color: #004000;">putObject</span><span style="color: #009900;">&#40;</span>S3<span style="color: #339933;">::</span><span style="color: #004000;">inputFile</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$FILE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$bucket</span><span style="color: #339933;">,</span> <span style="color: #000088;">$uri</span><span style="color: #339933;">,</span> S3<span style="color: #339933;">::</span><span style="color: #004000;">ACL_PUBLIC_READ</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Disposition'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'attachment; filename='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2009/09/23/forcing-files-to-download-from-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How we cache at CollegeHumor</title>
		<link>http://www.adamgotterer.com/2009/03/01/how-we-cache-at-collegehumor/</link>
		<comments>http://www.adamgotterer.com/2009/03/01/how-we-cache-at-collegehumor/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 22:21:52 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Caching]]></category>
		<category><![CDATA[CollegeHumor]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2009/03/01/how-we-cache-at-collegehumor/</guid>
		<description><![CDATA[CollegeHumor, like many websites that want to reduce database requests and speed up processing, uses memcached as a caching layer. This article will explain our software implementation and discuss a number of things we learned along the way. If you read my blog you will know I&#8217;m a PHP guy. CollegeHumor is also coded in [...]]]></description>
			<content:encoded><![CDATA[<p>CollegeHumor, like many websites that want to reduce database requests and speed up processing, uses memcached as a caching layer. This article will explain our software implementation and discuss a number of things we learned along the way. If you read my blog you will know I&#8217;m a PHP guy. CollegeHumor is also coded in PHP. None of the concepts covered in this post will be specific to any particular programming language. There will be a few simple PHP examples.</p>
<p>Let&#8217;s jump right into the class setup&#8230; Our cache class is a completely static class and can&#8217;t be instantiated on its own. When our application starts up a create_instance function is called which will create a connection to memcache in a static object stored in our class. Shortly after the instance is created, our config file is loaded and we add the servers that make up our memcache pool. Really nothing fancy happening thus far&#8230;</p>
<p>Besides the create_instance and the add_server functions our class only has three main public functions; get, set and delete. When I say main, those are really the only three functions we use throughout our application, everything else is for internal use by the cache class. There are also a few logging and stats functions which aren&#8217;t important for this article.</p>
<p><strong>Set Function</strong></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$expire</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span>1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$expire</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span>1<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// there was no key passed, to be safe we will create one</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">falsify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// set the instance cache</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$memcache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">dogpile_set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$expire</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> MEMCACHE_COMPRESSED<span style="color: #339933;">,</span> <span style="color: #000088;">$expire</span> <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">EXTENDED_LIFE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// set memcache</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p>Let me explain what&#8217;s going on and why&#8230; The set function takes 3 parameters: $key, $value and $expire.</p>
<p>1) Check the $expire value. If the expiration is less than zero (we default to -1) we assume this wasn&#8217;t meant to be cached and we just return true.</p>
<p>2) Make sure there was a $key passed. If there isn&#8217;t a key, we play it safe and set $key equal to the MD5 of the $value. Otherwise, there is a chance of key collisions. We definitely don&#8217;t want that.</p>
<p>3) We run the $value through a function called &#8220;falsify&#8221;. We found that storing the actual value of &#8220;false&#8221; caused a number of issues. The first being that we interface very closely with our database layer. If our get function returns false, the database layer assumes it didn&#8217;t find a value in cache and does a query (more on the solution to this in the get section). Second, the get function will return false when it fails to find data. The solution was the falsify function. It looks at the value and if it&#8217;s false the value is turned into a special string we can later identify. Something like &#8220;&lt;-F4LS3->&#8221;. Basically a value that would never normally be stored. Later on in the get function we will use this to identify the difference between a stored false and not finding results.</p>
<p>4) We created a local instance cache that stores any data we get/set in a static array. This helps prevent unnecessary subsequent requests for data we may have already retrieved. We do this by passing the key/value to an instance_set function which stores the data by its key.</p>
<p>5) Sites with high loads are often subject to the dogpile effect. Basically, if something falls out of cache and two or more users make the same request and receive a miss from memcache, they end up performing the same operation (usually a database query) to refresh the data. For smaller sites the extra database work is fairly minor. But larger sites under heavy load often can&#8217;t afford this. Think about something falling out of cache on the homepage of a large site. This could generate hundreds of the same query, locking up tables and eventually bring the database to a crawl. I have seen it, it&#8217;s not that awesome.</p>
<p>The way we deal with this problem is by passing the value and expiration time to a function called set_dogpile. This function is simple and you will understand its purpose later on&#8230; All this function does is create an array with the key &#8220;v&#8221; and stores the $value and a key called &#8220;t&#8221; where we store the $expire and then returns the array.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000000; font-weight: bold;">function</span> dogpile_set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$expire</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'t'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$expire</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'v'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p>6) Finally we can write our data to memcache! We set the key to the $key we were originally passed and the value to the array that was returned from dogpile_set. The expiration time is slightly more complicated. Our cache class has a constant variable called &#8220;extended_life&#8221;. We use this in conjunction with the dogpile effect prevention. Our extended life is set to 300 seconds. This will be better explained in the get section below, bare with me for now. Set the expiration to the $expire value passed in + the extended_life.</p>
<p>*Its important to note that the version of data stored in the instance cache (Step 4) is the original data, not the dogpile array.</p>
<p><strong>Get Function</strong></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$found</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Not used for the purpose of this article</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// $value = self::get_complex($key);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">get_simple</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$found</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$found</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// complex response (not used in this article)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">defalsify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// simple response</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p>The get function takes two parameters: The first is the $key and the second is an optional referenced parameter called &#038;$found (default to null).</p>
<p>Our get function can take two types of keys. Either a single key request as a string or multiple key requests as an array. The first thing we do in the get function is determine the key type. If it&#8217;s a string we send the key off to the &#8220;get_simple&#8221; function. If it&#8217;s an array it goes to the &#8220;get_complex&#8221; function. For simplicity reasons we are only going to focus on the get_basic function.</p>
<p>If you do explore get_complex on your own, keep in mind that memcache can take an array of keys and retrieve those results in a single request.  You will also need to keep track of what is and isn&#8217;t found from the instance cache. That way we can do lookups from memcache on the missed keys. There is an example of get_complex at the very end of this article, it should be easy to understand after you grasp get_basic.</p>
<p><span style="text-decoration: underline;">Get Simple</span></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000000; font-weight: bold;">function</span> get_simple<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// instance cache returned nothing, look it up</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">dogpile_get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$memcache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// results were found in memcache, lets add it to the instance cache</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// nothing was found, return</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p>1) First the key is passed to the &#8220;get_instance&#8221; function. This function checks our static instance array to see if we have already performed a get or set for that key. If data is found, return it, otherwise return false.</p>
<p>We are back in the get_basic function now. If the value returned from get_instance isn&#8217;t false, we  return the value back to &#8220;get&#8221;.</p>
<p>2) If the value returned from get_instance is false we need to ask memcache for the data. You should do that now.</p>
<p>Whatever the response is from memcache we will pass the key and the data to the dogpile_get function.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000000; font-weight: bold;">function</span> dogpile_get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'v'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'t'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'t'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'t'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">DELAY</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Update the cache time</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// set the stale value back to memcache for a short 'delay' so no one else tries to write the same data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$memcache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</span><span style="color: #339933;">,</span> MEMCACHE_COMPRESSED<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">DELAY</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p>a. First we need to make sure the value isn&#8217;t an empty array. If it fails that check we assume the data is corrupt or snuck into memcache and we return false. If everything looks good, extract the value from the &#8220;v&#8221; index and the time from the &#8220;t&#8221; index.</p>
<p>b. Make sure the &#8220;t&#8221; value is greater then 0. If its not, return the &#8220;v&#8221; value.</p>
<p>c. Check if the current time is greater than or equal to the &#8220;t&#8221; value. This is where our dogpile magic happens. The extended_life we set earlier gives us an extra few minutes to let the application determine what&#8217;s stale and what&#8217;s valid. The &#8220;t&#8221; value is the actual time we want the data to expire even thought we told memcache to store it for an extra few minutes. Since we got this far, it means the data is meant to expire. To prevent everyone and their mother from reloading the cache we are going to temporarily store the old stale data back in memcache while this user has the opportunity to refresh it.</p>
<p>We need to update the &#8220;t&#8221; value of the data array that was passed in to be the current time + $delay. Delay is a constant integer; we have out set to 30 seconds (change as needed). This delay is our dogpile buildup prevention. You will see how in a moment&#8230; Now we write the stale data back to memcache. Set the key to the $key that was passed in, the value to our updated $data array and the expiration to $delay. Now for the next 30 seconds all subsequent requests will receive the stale data (shouldn&#8217;t be a big deal for most sites). The user who found the stale data now has 30 seconds to complete an update. If she fails to do so, the next user to make the request will have that opportunity. Return false, because we want to the request to think we found nothing and fetch fresh data.</p>
<p>3) Now that we have our response and have dealt with dogpiling we need to analyze the response. If the value from get_simple is false we need to set &#038;$found to false and return false. The found variable does exactly as you probably guessed. It tells us if the get function really found something (even if the value was stored as false). It&#8217;s a referenced variable, so we can easily use it outside of the cache class.</p>
<p>If the response is not false we set &#038;$found to true and pass the data off to the defalsify function, which compares the value to our constant &#8220;false identifier&#8221; (&lt;-F4LS3->). If the value equals the identifier, return false. Now the &#8220;get&#8221; function can finally return the results.</p>
<p><strong>Delete Function</strong></p>
<p>The delete functionality is simple compared to the get/set functionality. The goal is to delete the data from the instance cache and from memcache. This is easily shown with an example.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$keys</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$memcache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
<p><strong>Conclusion</strong></p>
<p>I hope this article gives you a better insight into some more advanced caching techniques. I, nor CollegeHumor claim to have invented any of these techniques or methods. This was a high level overview of how our caching layer functions and I hope someone learned something from it. I know it might be difficult to follow all the operations, unfortunately I cant post the entire class code. But, if you have any questions about implementation, caching or anything PHP, feel free to contact me or post a comment.</p>
<p><span style="text-decoration: underline;">Get Complex</span></p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000000; font-weight: bold;">function</span> get_complex<span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$results</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$missing</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$num_keys</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// lets see if we can find any of these in the instance cache first</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$x</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$num_keys</span><span style="color: #339933;">;</span> <span style="color: #000088;">$x</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$keys</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// nothing was found in the instance cache, lets create a list to look them up in memcache &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$missing</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$key</span><span style="color: #339933;">;</span> &nbsp;&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// we found what we were looking for in instance cache! &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$results</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">defalsify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$missing</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$results</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// we found everything we need in instance cache &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// look up anything thats missing in memcache &nbsp; </span><br />
&nbsp; &nbsp; <span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$memcache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$missing</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">dogpile_get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$results</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">defalsify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">instance_set</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// we didnt find what we needed in memcache</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$results</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2009/03/01/how-we-cache-at-collegehumor/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>To CMS or not to CMS?</title>
		<link>http://www.adamgotterer.com/2009/02/12/to-cms-or-not-to-cms/</link>
		<comments>http://www.adamgotterer.com/2009/02/12/to-cms-or-not-to-cms/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 04:28:48 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2009/02/12/to-cms-or-not-to-cms/</guid>
		<description><![CDATA[In one of my recent posts someone asked in the comments what I thought about Drupal. It felt off topic, so I decided to write a post about Content Management Systems.
I personally don’t have much experience with open source (or enterprise) CMS. I had a short stint with Joomla and eventually ditched it. I have [...]]]></description>
			<content:encoded><![CDATA[<p>In one of my recent posts someone asked in the comments what I thought about Drupal. It felt off topic, so I decided to write a post about Content Management Systems.</p>
<p>I personally don’t have much experience with open source (or enterprise) CMS. I had a short stint with Joomla and eventually ditched it. I have become a bit of a development control freak. More often than not I prefer to roll my own system. This isn’t for everyone and doesn’t make sense for all projects.</p>
<p>My problem with pre designed Content Management Systems, is it tries to solve a problem that can’t always be solved with single solution. A fits everything package usually comes with overhead,  constraints and a little bit of a development black hole. These constraints can lead to excessive amounts of “work arounds”, hacks and a lack of understanding. On the other hand a pre packaged solution comes with an entire community of developers, tutorials, patches and plugins. Having resources like that can save time and money. It really comes down to what’s best for your project.</p>
<p>Choosing to build your own system or use an existing one depends on the scope of the project and your skill level. These are a few key points I would pay attention to while making a decision:</p>
<ul>
<li>How many users will be using your site? Theres a big difference between a 10 user intranet application and a million user application.</li>
<li>What is the timeline for development?</li>
<li>What kind of budget are you working with?</li>
<li>How active is the community that maintains and contributes to the CMS?</li>
<li>How much of the CMS will you have to customize? Are there plugins that do what you need?</li>
</ul>
<p>For a site like CollegeHumor, we needed to understand and control every line of code. Everything from the framework to the content management application is all home grown. But like I said before this doesn’t make sense for everyone. If you are building a small intranet site and can do the bulk of the work in a CMS, there is no reason to reinvent the wheel. If your site handles several million hits a day you may not want the extra overhead that a CMS comes with maybe rolling your own makes sense. Evaluate what you are working with and make a choice that best fits your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2009/02/12/to-cms-or-not-to-cms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Invite Bookmarklet</title>
		<link>http://www.adamgotterer.com/2009/02/04/facebook-invite-bookmarklet/</link>
		<comments>http://www.adamgotterer.com/2009/02/04/facebook-invite-bookmarklet/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 04:05:30 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2009/02/04/facebook-invite-bookmarklet/</guid>
		<description><![CDATA[One of the best Facebook features is the ability to invite friends to events. The most annoying part about this system is the inability to invite more then 100 friends at a time (Facebook: wheres the invite all!?). In the past I have clicked one by one and sent invites in blocks of 100. Today [...]]]></description>
			<content:encoded><![CDATA[<p>One of the best Facebook features is the ability to invite friends to events. The most annoying part about this system is the inability to invite more then 100 friends at a time (Facebook: wheres the invite all!?). In the past I have clicked one by one and sent invites in blocks of 100. Today was the day that I had enough! I made a bookmarklet to automate the bulk of the process. Unfortunately it can’t do all the work for you, but it will automatically adds users to the invite in blocks of 100 with a single click. Heres how it works&#8230;</p>
<p>Step 1) Log in to Facebook and browse to the event &#8220;Invite people to come&#8221; page.</p>
<p>2) Setup a new bookmarklet with this code (or optionally paste in the address bar on that page):</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">javascript<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">var</span> e<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>e.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'text/javascript'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>e.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'src'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>setTimeout<span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #003366; font-weight: bold;">var</span> friends <span style="color: #339933;">=</span> $$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#friends_list span input'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #003366; font-weight: bold;">var</span> offset <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span><span style="color: #000066;">prompt</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Please enter an offset'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>offset <span style="color: #339933;">&gt;</span> friends.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'All done!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> offset<span style="color: #339933;">;</span> x <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;=</span> offset <span style="color: #339933;">+</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>friends<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">onclick</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 3000<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>void<span style="color: #009900;">&#40;</span>0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>3) Click the bookmarklet and enter 0 when prompted. (0 represents your current offset, you will need to keep track of this.)</p>
<p>4) Click invite</p>
<p>5) Repeat and increase the offset by 100 until all friends have been sent invites</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2009/02/04/facebook-invite-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>PHP Recursive Multidimensional Array Flatten Using SPL</title>
		<link>http://www.adamgotterer.com/2008/12/19/php-recursive-multidimensional-array-flatten-using-spl/</link>
		<comments>http://www.adamgotterer.com/2008/12/19/php-recursive-multidimensional-array-flatten-using-spl/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 17:47:43 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2008/12/19/php-recursive-multidimensional-array-flatten-using-spl/</guid>
		<description><![CDATA[
function array_flatten_recursive&#40;$array&#41; &#123;
&#160; &#160; if&#40;$array&#41; &#123;
&#160; &#160; &#160; &#160; $flat = array&#40;&#41;;
&#160; &#160; &#160; &#160; foreach&#40;new RecursiveIteratorIterator&#40;new RecursiveArrayIterator&#40;$array&#41;, RecursiveIteratorIterator::SELF_FIRST&#41; as $key=&#62;$value&#41; &#123;
&#160; &#160; &#160; &#160; &#160; &#160; if&#40;!is_array&#40;$value&#41;&#41; &#123;
&#160; &#160; &#160; &#160; &#160; &#160; $flat&#91;&#93; = $value;
&#160; &#160; &#160; &#160; &#125;
&#160; &#160; &#125;

&#160; &#160; return $flat;
&#160; &#160; 
&#160; &#160; &#125; else &#123;
&#160; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">function</span> array_flatten_recursive<span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$flat</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> RecursiveIteratorIterator<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> RecursiveArrayIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> RecursiveIteratorIterator<span style="color: #339933;">::</span><span style="color: #004000;">SELF_FIRST</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$flat</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$flat</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000088;">$array</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">'A'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'B'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">'C'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 6<span style="color: #339933;">,</span>7<span style="color: #339933;">,</span>8<span style="color: #339933;">,</span>9<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span>array_flatten_recursive<span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
</pre>
<p>&#8211; Response:</p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Array (<br />
&nbsp; &nbsp; [0] =&gt; 1<br />
&nbsp; &nbsp; [1] =&gt; 2<br />
&nbsp; &nbsp; [2] =&gt; 3<br />
&nbsp; &nbsp; [3] =&gt; 4<br />
&nbsp; &nbsp; [4] =&gt; 5<br />
&nbsp; &nbsp; [5] =&gt; 6<br />
&nbsp; &nbsp; [6] =&gt; 7<br />
&nbsp; &nbsp; [7] =&gt; 8<br />
&nbsp; &nbsp; [8] =&gt; 9<br />
)<br />
&lt;/pre&gt;</div></div>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2008/12/19/php-recursive-multidimensional-array-flatten-using-spl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recursive PHP in_array function</title>
		<link>http://www.adamgotterer.com/2008/07/22/recursive-php-in_array-function/</link>
		<comments>http://www.adamgotterer.com/2008/07/22/recursive-php-in_array-function/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 23:41:51 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2008/07/22/recursive-php-in_array-function/</guid>
		<description><![CDATA[I needed a recursive in_array function the other day and disliked all the samples I found on php.net. I wrote this one using the StandardPHPLibrary. It will recursively search through a multidimensional array and return true if the $needle is found in the $haystack.

function in_array_recursive&#40;$needle, $haystack&#41; &#123;

&#160; &#160; $it = new RecursiveIteratorIterator&#40;new RecursiveArrayIterator&#40;$haystack&#41;&#41;;

&#160; &#160; foreach&#40;$it [...]]]></description>
			<content:encoded><![CDATA[<p>I needed a recursive <a href="http://www.php.net/in_array">in_array</a> function the other day and disliked all the samples I found on php.net. I wrote this one using the <a href="http://www.php.net/spl">StandardPHPLibrary</a>. It will recursively search through a multidimensional array and return true if the $needle is found in the $haystack.</p>
<pre>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">function</span> in_array_recursive<span style="color: #009900;">&#40;</span><span style="color: #000088;">$needle</span><span style="color: #339933;">,</span> <span style="color: #000088;">$haystack</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000088;">$it</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecursiveIteratorIterator<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> RecursiveArrayIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$haystack</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$it</span> <span style="color: #b1b100;">AS</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$element</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$needle</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2008/07/22/recursive-php-in_array-function/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Weebly Puzzle</title>
		<link>http://www.adamgotterer.com/2008/05/28/weebly-puzzle/</link>
		<comments>http://www.adamgotterer.com/2008/05/28/weebly-puzzle/#comments</comments>
		<pubDate>Wed, 28 May 2008 05:06:51 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2008/05/28/weebly-puzzle/</guid>
		<description><![CDATA[This site attracts a decent amount of JavaScript folks so I thought this would be relevant and maybe even helpful. I read news.ycombinator.com everyday (or several times a day). If you are into the startup world, you should as well. It has by far the best startup news and a great community. The feedback and [...]]]></description>
			<content:encoded><![CDATA[<p>This site attracts a decent amount of JavaScript folks so I thought this would be relevant and maybe even helpful. I read <a href="http://news.ycombinator.com">news.ycombinator.com</a> everyday (or several times a day). If you are into the startup world, you should as well. It has by far the best startup news and a great community. The feedback and questions posted on there are generally informative and trolling is at a bare minimum. It&#8217;s what reddit used to be. Regardless, I came across a job posting at <a href="http://www.weebly.com">Weebly</a> for a web developer position. The job description came with a little JavaScript puzzle. I had no intention of actually applying for the job, but when ever I find these puzzles I like to do them. I&#8217;m not going to post the results, because thats not cool. If you want to check your answer email me your best guess. But it entertained me for about 20 minutes. So if you&#8217;re bored or actually looking for a job check it out at <a href="http://www.weebly.com/jobs.html">http://www.weebly.com/jobs.html</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2008/05/28/weebly-puzzle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Muxtape&#8217;s Is Growing Fast!</title>
		<link>http://www.adamgotterer.com/2008/04/03/muxtapes-is-growing-fast/</link>
		<comments>http://www.adamgotterer.com/2008/04/03/muxtapes-is-growing-fast/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 18:09:42 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2008/04/03/muxtapes-is-growing-fast/</guid>
		<description><![CDATA[
On Tuesday March 25th, Justin Ouellette one of the developers from Vimeo launched Muxtape as a side project. The idea isn&#8217;t totally original, but its executed far better then the competition. Muxtape is a site that lets you make virtual mix tapes. You upload up to 12 songs from your computer and share the custom [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.muxtape.com"><img src='http://www.adamgotterer.com/wp-content/uploads/2008/04/muxtape.jpg' alt='Muxtape' /></a></p>
<p>On Tuesday March 25th, <a href="http://justinouellette.com/">Justin Ouellette</a> one of the developers from Vimeo launched <a href="http://www.muxtape.com">Muxtape</a> as a side project. The idea isn&#8217;t totally original, but its executed far better then the competition. Muxtape is a site that lets you make virtual mix tapes. You upload up to 12 songs from your computer and share the custom link with anyone who wants to listen. The design is one of the cleanest and easiest to use sites I have ever seen.</p>
<p>When Justin sent out an office wide link looking for feedback on Tuesday morning I googled &#8220;muxtape&#8221; and got back 33 results. I did the same thing the Wednesday and got back around 4,000 results. Thursday was around 9,000 and Friday around 22,000. I didn&#8217;t check over the weekend. I looked sometime early the next week and saw it was over 40,000. Tuesday April 1st, one week after the site launched google returned just over 100,000 results and as of today (April 4th) 121,000 result. That growth rate is pretty unbelievable and I would love to see at what point it stabilizes.</p>
<p>I talked to Justin today about the growth on his site, I don&#8217;t want to throw numbers out without his permission but he said the site is growing at a nice rate every day. I assure you it&#8217;s a pretty impressive number for a site two weeks old. He must be paying a fortune in bandwidth on Amazon S3. I want to say that he didn&#8217;t have a clue how big this was going to get, but then I would be lying. I think he knew damn well how the site was going to do before he even launched. He gave Vimeo two weeks notice Monday, the day before he launched. Thats a pretty ballsy move to go from a stable income to the unknown. But thats what separates the people who build great companies and the people who are too afraid and work corporate the rest of their life. I don&#8217;t know Justin that well, but I have had some interesting conversations with him and he really knows his stuff. He didn&#8217;t give me much insight to future plans. But he said theres a monetization plan in the works and a bunch of new feature. I think he is going to do great and wish him the best of luck.</p>
<p><a href="http://adamg.muxtape.com">Check out my Muxtape!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2008/04/03/muxtapes-is-growing-fast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BustedTees Relaunch</title>
		<link>http://www.adamgotterer.com/2008/04/01/bustedtees-relaunch/</link>
		<comments>http://www.adamgotterer.com/2008/04/01/bustedtees-relaunch/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 21:07:00 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[BustedTees]]></category>
		<category><![CDATA[Connected Ventures]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.adamgotterer.com/2008/04/01/bustedtees-relaunch/</guid>
		<description><![CDATA[
This morning at 5am Kunal Shah, Nick Dunkman, Jmo and myself launched a new version of the BustedTees website! Visually the site hasn&#8217;t changed much. Amir Cohen, one the front end developer for CollegeHumor did an excellent job recoding the front end. We spent the better part of the last 4 months recoding everything from [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bustedtees.com"><img src='http://www.adamgotterer.com/wp-content/uploads/2008/04/bt_logo.gif' alt='BustedTees' /></a></p>
<p>This morning at 5am Kunal Shah, Nick Dunkman, <a href="http://joshmohrer.com/">Jmo</a> and myself launched a new version of the <a href="http://www.bustedtees.com">BustedTees</a> website! Visually the site hasn&#8217;t changed much. <a href="http://www.amircohen.com/">Amir Cohen</a>, one the front end developer for CollegeHumor did an excellent job recoding the front end. We spent the better part of the last 4 months recoding everything from scratch. The original version was built on the open source <a href="http://www.symfony-project.org/">Symfony PHP framework</a> several years ago (before my time). The site served it&#8217;s purpose and helped take BustedTees to a new level, it wasn&#8217;t that it was poorly programmed, it just outgrew our requirements. </p>
<p><img width="400" height="275" src='http://www.adamgotterer.com/wp-content/uploads/2008/04/bm3zcorof79t31797yabgkqs_500.jpg' alt='BustedTees at 5am' /><br />(Dev Team at 5:15am)</p>
<p>I&#8217;m finding that a lot of the open source PHP frameworks that I have experimented with and seen throughout the community just don&#8217;t scale well. They serve a purpose and are great for average every day sites. But when dealing with a site the size of a BustedTees or CollegeHumor it really makes sense to roll your own framework, if you can. There are of course instances when writing a framework from scratch doesn&#8217;t always make sense. In the &#8220;unsure&#8221; startup setting it sometimes makes sense to get something out there quick and worry about scaling later. Scaling is a GREAT problem to have. If you are going to use open source code, not just frameworks, it&#8217;s important to really understand the underlying code. I can bet most coders don&#8217;t have a clue how the open source code they use actually works. Some of these applications are coded by excellent developers, you might learn something new by just reading their code.</p>
<p>Working on BustedTees has been an incredible experience and I have learned so much. I have worked on some small ecommerce sites as a freelance developer, but nothing of this size. Theres so many things I would have never thought needed to be accounted for. In future posts I will try and elaborate a bit. Right now I&#8217;m running on a few hours of sleep I got from a nap, so I&#8217;m going to pass out&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adamgotterer.com/2008/04/01/bustedtees-relaunch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
