<?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>Matthew Turland &#187; SPL</title>
	<atom:link href="http://matthewturland.com/tag/spl/feed/" rel="self" type="application/rss+xml" />
	<link>http://matthewturland.com</link>
	<description></description>
	<lastBuildDate>Sun, 18 Jul 2010 14:29:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>New SPL Features in PHP 5.3</title>
		<link>http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/</link>
		<comments>http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/#comments</comments>
		<pubDate>Thu, 20 May 2010 15:00:53 +0000</pubDate>
		<dc:creator>Matthew Turland</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://matthewturland.com/?p=107</guid>
		<description><![CDATA[Note: I&#8217;ve written on this topic before, but thought the subject warranted further more detailed discussion and a more comprehensive and up-to-date set of benchmarks. Hence, this post and this presentation. Enjoy. The SPL, or Standard PHP Library, is an often overlooked extension in the PHP core. It first came on the scene in PHP [...]]]></description>
			<content:encoded><![CDATA[<p><em>Note: I&#8217;ve <a title="The SPL Deserves Some Reiteration | Blue Parabola, LLC" href="http://blueparabola.com/blog/spl-deserves-some-reiteration">written on this topic before</a>, but thought the subject warranted further more detailed discussion and a more comprehensive and up-to-date set of benchmarks. Hence, this post and <a title="New SPL Features in PHP 5.3" href="http://www.slideshare.net/tobias382/new-spl-features-in-php-53">this presentation</a>. Enjoy.</em></p>
<p>The <a title="PHP: SPL - Manual" href="http://php.net/spl">SPL</a>, or Standard PHP Library, is an often overlooked extension in the PHP core. It first came on the scene in PHP 5 and a variety of <a title="PHP: Iterators - Manual" href="http://php.net/manual/en/spl.iterators.php">iterators</a> constituted the majority of its initial offerings. Though the <a title="PHP: New Classes - Manual" href="http://www.php.net/manual/en/migration53.classes.php">iterator offerings were expanded in PHP 5.3</a>, the particularly interesting additions to the SPL were several specialized <a title="Data structure - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Data_structures">data structure</a> <a title="PHP: Datastructures - Manual" href="http://php.net/manual/en/spl.datastructures.php">classes</a>, the foundational concepts for which originate in the field of <a title="Computer science - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Computer_science">computer science</a>. In this post, I will provide an overview of these new classes and explain why and when they should be used.</p>
<h3>Arrays</h3>
<p>While PHP has several data types, the ones that likely see the most frequent and varied use are <a title="PHP: Strings - Manual" href="http://php.net/manual/en/language.types.string.php">strings</a> and <a title="PHP: Arrays - Manual" href="http://php.net/manual/en/language.types.array.php">arrays</a>. They are the proverbial <a title="Duct tape - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Duct_tape#Common_uses">duct tape</a> and <a title="WD-40 - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/WD-40#Function">WD-40</a> of PHP, respectively. Like arrays, SPL data structure classes are used to store composite (i.e. non-<a title="Scalar (computing) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Scalar_(computing)">scalar</a>) data.</p>
<p>Now, that&#8217;s not to say that every instance of an array in existing codebases should be replaced with an SPL container object. There are cases where it&#8217;s appropriate to use one over the other. Knowing the difference requires an understanding of how arrays work.</p>
<p>Within the C code that makes up the PHP interpreter, arrays are implemented as a data structure called a <a title="Hash table - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Hash_table">hash table or hash map</a>. When a value contained within an array is referenced by its index, PHP uses a <a title="[svn] Contents of /php/php-src/trunk/Zend/zend_hash.h" href="http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_hash.h?revision=298204&amp;view=markup#l228">hashing function</a> to convert that index into a unique hash representing the location of the corresponding value within the array.</p>
<p>This hash map implementation enables arrays to store an arbitrary number of elements and provide access to all of those elements simultaneously using either numeric or string keys. Arrays are extremely fast for the capabilities they provide and are an excellent general purpose data structure.</p>
<h3>Fixed Arrays</h3>
<p>In contrast to arrays, <a title="PHP: SplFixedArray - Manual" href="http://php.net/manual/en/class.splfixedarray.php"><code>SplFixedArray</code></a> functions more like <a title="Arrays" href="http://www.cplusplcom/doc/tutorial/arrays/">C arrays</a> or <a title="Arrays (The Java™ Tutorials &gt; Learning the Java Language &gt; Language Basics)" href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/arrays.html">Java arrays</a> than <a title="PHP: Arrays - Manual" href="http://php.net/manual/en/language.types.array.php">PHP arrays</a>. The maximum number of elements that it may contain is specified upon instantiation. While it is possible to change it later via the <code>setSize()</code> method, this negates the performance advantages of using it: because its size is fixed, it doesn&#8217;t need to use a hashing function to resolve the position of elements within the array. <strong>It makes sense to use fixed arrays when the number of elements to be stored is known in advance and the elements only need to be accessed by sequential position.</strong></p>
<p><code>SplFixedArray</code> implements the <a title="SPL-StandardPHPLibrary: Iterator Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></a>, <a title="SPL-StandardPHPLibrary: ArrayAccess Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html"><code>ArrayAccess</code></a>, and <a title="SPL-StandardPHPLibrary: Countable Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></a> interfaces. <code>Iterator</code> allows it to be iterated using a <a title="PHP: foreach - Manual" href="http://php.net/manual/en/control-structures.foreach.php"><code>foreach</code></a> loop. <code>ArrayAccess</code> provides access to its elements using <a title="PHP: Arrays - Manual" href="http://php.net/manual/en/language.types.array.php#language.types.array.syntax.modifying">array syntax</a> where elements are referred to using integer positions beginning at 0 as with enumerated arrays. <code>Countable</code> enables a list to be passed to the <a title="PHP: count - Manual" href="http://php.net/count"><code>count()</code></a> function like an array.</p>
<p>Aside from the inability to use it in place of arrays with <a title="PHP: Array Functions - Manual" href="http://php.net/manual/en/ref.array.php">array functions</a>, instances of <code>SplFixedArray</code> function just like arrays for all intents and purposes. It&#8217;s even possible to convert them to and from arrays using the <a title="PHP: SplFixedArray::toArray - Manual" href="http://php.net/manual/en/splfixedarray.toarray.php"><code>toArray()</code></a> and <a title="PHP: SplFixedArray::fromArray - Manual" href="http://php.net/manual/en/splfixedarray.fromarray.php"><code>fromArray()</code></a> methods respectively. However, it generally makes more sense to use <code>SplFixedArray</code> exclusively for each individual use case.</p>
<h3>Lists</h3>
<p>In <a title="Computer science - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Computer_science">computer science</a>, a <a title="List (computing) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/List_(computing)">list</a> is defined as an ordered collection of values. A <a title="Linked list - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Linked_list">linked list</a> is a data structure in which each element in the list includes a reference to one or both of the elements on either side of it within the list. The term &#8220;<a title="Doubly-linked list - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Doubly-linked_list">doubly-linked list</a>&#8221; is used to refer to the latter case. In the SPL, this takes the form of the class <a title="PHP: SplDoublyLinkedList - Manual" href="http://php.net/manual/en/class.spldoublylinkedlist.php"><code>SplDoublyLinkedList</code></a>.</p>
<p>Like <code>SplFixedArray</code>, <code>SplDoublyLinkedList</code> also implements the <a title="SPL-StandardPHPLibrary: Iterator Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></a>, <a title="SPL-StandardPHPLibrary: ArrayAccess Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html"><code>ArrayAccess</code></a>, and <a title="SPL-StandardPHPLibrary: Countable Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></a> interfaces. In addition to the methods that come with these interface implementations, elements can be added to or removed from the start or end of the list using its <a title="PHP: SplDoublyLinkedList::push - Manual" href="http://php.net/manual/en/spldoublylinkedlist.push.php"><code>push()</code></a>, <a title="PHP: SplDoublyLinkedList::pop - Manual" href="http://php.net/manual/en/spldoublylinkedlist.pop.php"><code>pop()</code></a>, <a title="PHP: SplDoublyLinkedList::shift - Manual" href="http://php.net/manual/en/spldoublylinkedlist.shift.php"><code>shift()</code></a> and <a title="PHP: SplDoublyLinkedList::unshift - Manual" href="http://php.net/manual/en/spldoublylinkedlist.unshift.php"><code>unshift()</code></a> methods, which correspond to the <a title="PHP: array_push - Manual" href="http://php.net/array_push"><code>array_push()</code></a>, <a title="PHP: array_pop - Manual" href="http://php.net/array_pop"><code>array_pop()</code></a>, <a title="PHP: array_shift - Manual" href="http://php.net/array_shift"><code>array_shift()</code></a>, and <a title="PHP: array_unshift - Manual" href="http://php.net/array_unshift"><code>array_unshift()</code></a> functions respectively. Unfortunately, as of PHP 5.3.2, there&#8217;s no way to insert an element anywhere in the list other than at the beginning or the end. A <a title="PHP Bugs: #48358: SplDoublyLinkedList needs an insertAfterIterator() method or something similar" href="http://bugs.php.net/bug.php?id=48358">feature request</a> has been filed for this. Add a comment or vote to show support for its addition.</p>
<p>The elements at the start and end of the list are accessible via its <a title="PHP: SplDoublyLinkedList::top - Manual" href="http://php.net/manual/en/spldoublylinkedlist.top.php"><code>top()</code></a> and <a title="PHP: SplDoublyLinkedList::bottom - Manual" href="http://php.net/manual/en/spldoublylinkedlist.bottom.php"><code>bottom()</code></a> methods respectively, which correspond to the <a title="PHP: reset - Manual" href="http://php.net/manual/en/function.reset.php"><code>reset()</code></a> and <a title="PHP: end - Manual" href="http://php.net/manual/en/function.end.php"><code>end()</code></a> functions. Like <code>SplFixedArray</code>, elements can also be accessed arbitrarily by positional index using the array syntax granted by <code>ArrayAccess</code>. <strong>It makes sense to use lists when the number of elements to be stored is not known in advance and the elements only need to be accessed by sequential position.</strong></p>
<h3>Stacks</h3>
<p><a title="Stack (data structure) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Stack_(data_structure)">Stacks</a> are similar to lists with two major differences. First, elements can only be added to the top of the stack. Second, an element can only be accessed by taking it off the top of the stack. Because of these differences, the stack is often referred to as a Last-In-First-Out or <a title="LIFO (computing) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/LIFO_(computing)">LIFO</a> data structure. <a title="PHP: SplStack - Manual" href="http://php.net/manual/en/class.splstack.php"><code>SplStack</code></a> is the SPL stack implementation.</p>
<p><code>SplStack</code> is a bit removed from the traditional definition of a stack. It extends <code>SplDoublyLinkedList</code> and inherits its abilities, some of which don&#8217;t really apply to stacks. In order to enforce its restriction on how elements are accessed, <code>SplStack</code> overrides the <a title="PHP: SplDoublyLinkedList::setIteratorMode - Manual" href="http://php.net/manual/en/spldoublylinkedlist.setiteratormode.php"><code>setIteratorMode()</code></a> method of its parent class and implements <a title="PHP: SplStack::setIteratorMode - Manual" href="http://php.net/manual/en/splstack.setiteratormode.php">its own</a> to prevent modification of the iteration direction. Both methods allow elements to be retained or removed as they are iterated.</p>
<p><strong>Use of stacks makes sense when the number of elements to be stored is not known in advance and the only element that must be accessible is the last one stored.</strong> However, as of PHP 5.3.2, the performance of <code>SplStack</code> leaves something to be desired. Benchmarks included later in this provide an objective illustration of this, though the cause of the behavior remains unknown.</p>
<h3>Queues</h3>
<p><a title="Queue (data structure) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Queue_(data_structure)">Queues</a> are also similar to lists, again with two major differences. First, elements can only be added (or &#8220;enqueued&#8221;) to the end of the queue. Second, an element can only be accessed by removing (or &#8220;dequeueing&#8221;) it from the beginning of the queue. For these reasons the queue is referred to as a First-In-First-Out or <a title="FIFO - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/FIFO">FIFO</a> data structure. The <a title="PHP: SplQueue - Manual" href="http://php.net/manual/en/class.splqueue.php"><code>SplQueue</code></a> class implements this data structure in the SPL.</p>
<p><code>SplQueue</code> follows suit with <code>SplStack</code> in extending <code>SplDoublyLinkedList</code>. Just as <code>SplStack</code> resultingly inherits some operations with at least questionable applicability, so too does <code>SplQueue</code>. Likewise, it overrides <code>setIteratorMode()</code> with <a title="PHP: SplQueue::setIteratorMode - Manual" href="http://php.net/manual/en/splqueue.setiteratormode.php">its own version</a> to restrict how elements are accessed. <strong>Use of queues makes sense when the number of elements to be stored is not known in advance and the only element that must be accessible is the remaining element that was stored earliest.</strong></p>
<p>One minor difference between <code>SplQueue</code> and <code>SplStack</code> is that the former contains two method aliases named after conceptual queue operations: <a title="PHP: SplQueue::dequeue - Manual" href="http://php.net/manual/en/splqueue.dequeue.php"><code>dequeue()</code></a> aliases <a title="PHP: SplDoublyLinkedList::shift - Manual" href="http://php.net/manual/en/spldoublylinkedlist.shift.php"><code>SplDoublyLinkedList::shift()</code></a> and <a title="PHP: SplQueue::enqueue - Manual" href="http://php.net/manual/en/splqueue.enqueue.php"><code>enqueue()</code></a> aliases <a title="PHP: SplDoublyLinkedList::push - Manual" href="http://php.net/manual/en/spldoublylinkedlist.push.php"><code>SplDoublyLinkedList::push()</code></a>. This makes sense because while <code>push()</code> and <code>pop()</code> share similar applicability to conceptual stack operations, they are already present in its parent class.</p>
<p>Despite their common ancestry, <code>SplQueue</code> appears to have better performance than <code>SplStack</code> as of PHP 5.3.2. Benchmarks included later in this post review this in more detail.</p>
<h3>Heaps</h3>
<p>Up to this point, the data structures discussed have resembled lists insofar as they contain elements in the order in which they were added. By contrast, when an element is added to a <a title="Heap (data structure) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Heap_(data_structure)">heap</a>, a comparison function is used to compare the new element to other elements already in the heap and element is placed appropriately within the heap based on that function&#8217;s return value. The beauty of heaps is that their underlying algorithm does this with minimal element comparisons, so it&#8217;s extremely efficient. <strong>Using heaps makes sense when the number of elements to be stored is not known in advance and elements must be accessed in an order based on how they compare to each other.</strong></p>
<p><a title="PHP: SplHeap - Manual" href="http://php.net/manual/en/class.splheap.php"><code>SplHeap</code></a> is an abstract class used to create a heap by extending it and providing a comparison function in the form of its <a title="PHP: SplHeap::compare - Manual" href="http://php.net/manual/en/splheap.compare.php"><code>compare()</code></a> method. Only the root element of a heap, the one yielding the highest comparison function return value, may be accessed or removed from the heap at any given time. This is done using the <a title="PHP: SplHeap::extract - Manual" href="http://php.net/manual/en/splheap.extract.php"><code>extract()</code></a> method of <code>SplHeap</code>. <code>SplHeap</code> implements the <a title="SPL-StandardPHPLibrary: Iterator Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></a> and <a title="SPL-StandardPHPLibrary: Countable Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></a> interfaces but, because only the root element can be extracted, it does not implement the <a title="SPL-StandardPHPLibrary: ArrayAccess Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html"><code>ArrayAccess</code></a> interface like the previously discussed data structure classes.</p>
<p>In addition to the abstract <code>SplHeap</code> class, two concrete implementations are also included in the SPL, namely <a title="PHP: SplMinHeap - Manual" href="http://php.net/manual/en/class.splminheap.php"><code>SplMinHeap</code></a> and <a title="PHP: SplMaxHeap - Manual" href="http://php.net/manual/en/class.splmaxheap.php"><code>SplMaxHeap</code></a>. The <a title="PHP: SplMinHeap::compare - Manual" href="http://php.net/manual/en/splminheap.compare.php"><code>compare()</code></a> method of <code>SplMinHeap</code> returns a value such that the smallest element in the heap is the root element. Likewise, the <a title="PHP: SplMaxHeap::compare - Manual" href="http://php.net/manual/en/splmaxheap.compare.php"><code>compare()</code></a> method of <code>SplMaxHeap</code> returns a value such that the largest element in the heap is the root element.</p>
<p>At first glance, using a subclass of <code>SplHeap</code> may seem equivalent to calling <a title="PHP: sort - Manual" href="http://php.net/sort"><code>sort()</code></a> or a similar function on an array and accessing the elements in sequence. This is indeed the case if all elements are added to the array prior to it being sorted. However, situations such as elements arriving over time or inadequate memory to store all elements simultaneously may preclude this approach. Use of arrays in such situations would require repeated resorting of the entire array as new elements are added, which is inefficient. This is why using the corresponding heap class makes a lot more sense in that situation than repeated calls to <a title="PHP: sort - Manual" href="http://php.net/sort"><code>sort()</code></a>, <a title="PHP: min - Manual" href="http://php.net/manual/en/function.min.php"><code>min()</code></a> or <a title="PHP: max - Manual" href="http://php.net/manual/en/function.max.php"><code>max()</code></a>. Additionally, <code>SplHeap</code> can be used to implement the <a title="Heapsort - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Heapsort">heapsort algorithm</a>, which has better worst case performance versus the <a title="Quicksort - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Quicksort">quicksort algorithm</a> <a title="[svn] Contents of /php/php-src/trunk/Zend/zend_qsort.c" href="http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_qsort.c?revision=296679&amp;view=markup#l56">implementation</a> <a title="[svn] Contents of /php/php-src/trunk/ext/standard/array.c" href="http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/array.c?revision=298204&amp;view=markup#l541">used by arrays</a>.</p>
<h3>Priority Queues</h3>
<p><a title="Priority queue - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Priority_queue">Priority queues</a> are somewhat similar to heaps. In fact, while it doesn&#8217;t extend <code>SplHeap</code>, <a title="PHP: SplPriorityQueue - Manual" href="http://php.net/manual/en/class.splpriorityqueue.php"><code>SplPriorityQueue</code></a> does make use of a heap structure internally to implement its functionality. The difference is that the <a title="PHP: SplPriorityQueue::insert - Manual" href="http://www.php.net/manual/en/splpriorityqueue.insert.php"><code>insert()</code></a> method of <code>SplPriorityQueue</code> queue accepts both a value and an associated priority, removing the need to use an array or object to store both of these and define an appropriate comparison function in an <code>SplHeap</code> instance. Elements with the highest priority, like those in <code>SplMaxHeap</code> with the highest value, are the ones that come out first when <a title="PHP: SplPriorityQueue::extract - Manual" href="http://php.net/manual/en/splpriorityqueue.extract.php"><code>extract()</code></a> is called. Note that elements with equal priority are returned in no particular order.</p>
<p>For reasons similar to those of <code>SplHeap</code>, <code>SplPriorityQueue</code> implements both <a title="SPL-StandardPHPLibrary: Iterator Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></a> and <a title="SPL-StandardPHPLibrary: Countable Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></a> interfaces and does not implement the <a title="SPL-StandardPHPLibrary: ArrayAccess Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html"><code>ArrayAccess</code></a> interface. Because it stores a value and priority per element, <code>SplPriorityQueue</code> includes a <a title="PHP: SplPriorityQueue::setExtractFlags - Manual" href="http://php.net/manual/en/splpriorityqueue.setextractflags.php"><code>setExtractFlags()</code></a> method that modifies the behavior of <code>extract()</code> to return the stored value, the stored priority, or an array containing both. Priorities are not bound to a particular data type: strings, integers, or even composite data types can be used. <code>SplPriorityQueue</code> can be extended and its <a title="PHP: SplPriorityQueue::compare - Manual" href="http://www.php.net/manual/en/splpriorityqueue.compare.php"><code>compare()</code></a> method overridden to customize the comparison logic.</p>
<p><strong>It makes sense to use a priority queue when the number of elements to be stored is not known in advance and elements must be accessed in an order based on how a value associated with each element (versus the element value itself) compares to the same associated values of other elements.</strong></p>
<h3>Sets and Composite Hash Maps</h3>
<p><a title="PHP: SplObjectStorage - Manual" href="http://php.net/manual/en/class.splobjectstorage.php"><code>SplObjectStorage</code></a> combines some of the properties of two different data structures. First, it provides the same functionality of a <a title="Hash table - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Hash_table">hash table</a> that a normal array has, but without its associated inability to use objects as keys unless the <a title="PHP: spl_object_hash - Manual" href="http://php.net/spl_object_hash"><code>spl_object_hash()</code></a> function is used. In other words, it implements a composite hash map. Second, it can be used as a <a title="Set (computer science) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Set_(computer_science)">set</a> to store objects as data without a meaningful corresponding key or concept of sequential order.</p>
<p>Its <a title="PHP: SplObjectStorage::attach - Manual" href="http://php.net/manual/en/splobjectstorage.attach.php"><code>attach()</code></a> method accepts an object key and the data to associate with it and its <a title="PHP: SplObjectStorage::detach - Manual" href="http://php.net/manual/en/splobjectstorage.detach.php"><code>detach()</code></a> method allows data to be removed using its associated object key. To use the object as a set, simply exclude the <code>$data</code> parameter for <code>attach()</code> as it&#8217;s optional. The <a title="Set (computer science) - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Set_(computer_science)#Operations">set operations</a> implemented by <code>SplObjectStorage</code> all have array function counterparts. For example, the <a title="PHP: SplObjectStorage::addAll - Manual" href="http://php.net/manual/en/splobjectstorage.addall.php"><code>addAll()</code></a> method and <a title="PHP: array_merge - Manual" href="http://php.net/manual/en/function.array-merge.php"><code>array_merge()</code></a> function both correspond to the union set operation. The difference operation is available using the <a title="PHP: SplObjectStorage::removeAll - Manual" href="http://php.net/manual/en/splobjectstorage.removeall.php"><code>removeAll()</code></a> method and <a title="PHP: array_diff - Manual" href="http://php.net/manual/en/function.array-diff.php"><code>array_diff()</code></a> function and its variants. The <a title="PHP: SplObjectStorage::contains - Manual" href="http://php.net/manual/en/splobjectstorage.contains.php"><code>contains()</code></a> method and <a title="PHP: in_array - Manual" href="http://php.net/manual/en/function.in-array.php"><code>in_array()</code></a> function both implement the element_of operation. Sadly, only arrays have an implementation of the intersection operation in the form of <a title="PHP: array_intersect - Manual" href="http://php.net/manual/en/function.array-intersect.php"><code>array_intersect()</code></a> and its variants. Tobias Schlitt has a <a title="Python. Good, bad, evil -2-: Native sets - Blog - Open Source - schlitt.info" href="http://schlitt.info/opensource/blog/0722_python_good_bad_evil_02_native_sets.html">more in-depth analysis</a> of this data structure that includes implementations of the set operations lacking in the SPL itself.</p>
<p>Like some of the other data structures in the SPL, <code>SplObjectStorage</code> implements the <a title="SPL-StandardPHPLibrary: Iterator Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></a>, <a title="SPL-StandardPHPLibrary: Countable Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></a>, and <a title="SPL-StandardPHPLibrary: ArrayAccess Interface Reference" href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html"><code>ArrayAccess</code></a> interfaces. Oddly, it also implements the <a title="PHP: Traversable - Manual" href="http://php.net/manual/en/class.traversable.php"><code>Traversable</code></a> interface (which is limited to internally defined classes and negates the need for implementation of the <code>Iterator</code> interface) and the <a title="PHP: Serializable - Manual" href="http://php.net/manual/en/class.serializable.php"><code>Serializable</code></a> interface (and it is the only SPL data structure class to do so).</p>
<p><strong>Using this class makes sense when data must be stored using composite keys or the ability to access data using set operations is more important than accessing data in a specific order.</strong></p>
<h3>Benchmarks</h3>
<p><em>Standard disclaimer: There are <a title="Lies, damned lies, and statistics - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Lies,_damned_lies,_and_statistics">lies, damned lies, and benchmarks</a>. <a title="your mileage may vary - Wiktionary" href="http://en.wiktionary.org/wiki/your_mileage_may_vary"><acronym title="Your Mileage May Vary">YMMV</acronym></a>.</em></p>
<h4>Platform</h4>
<ul>
<li>System: <a title="VGN-NR298E/S | VAIO® NR Series Notebook PC | Sony | SonyStyle USA" href="http://www.sonystyle.com/webapp/wcs/stores/servlet/ProductDisplay?storeId=10151&amp;catalogId=10551&amp;langId=-1&amp;productId=8198552921665293693#specifications">Sony Vaio VGN-NR298E</a></li>
<li>CPU: <a title="Intel® Core™2 Duo Processor T5550 (2M Cache, 1.83 GHz, 667 MHz FSB) with SPEC Code(s) SLA4E" href="http://ark.intel.com/Product.aspx?id=32427&amp;processor=T5550&amp;spec-codes=SLA4E">Intel Core2Duo 1.83GHz</a></li>
<li>RAM: 4 GB DDR2</li>
<li>OS: <a title="Ubuntu Home Page | Ubuntu" href="http://www.ubuntu.com/">Ubuntu</a> 9.10 Karmic Koala Desktop Edition 64-bit</li>
<li>PHP: Custom build of <a title="PHP: Downloads" href="http://www.php.net/downloads.php#v5.3.2">5.3.2</a> (<a title="PHP 5.3 on Ubuntu — Third Party Code" href="http://thirdpartycode.com/2009/08/building-php-5-3-packages-on-ubuntu-9-04-jaunty-for-apache-2/">here&#8217;s how to create one</a>) using this configuration: <code>--without-pear --without-sqlite --without-sqlite3 --without-pdo-sqlite</code></li>
</ul>
<h4>Process</h4>
<p>Code used is located in <a title="elazar's spl-benchmarks at master - GitHub" href="http://github.com/elazar/spl-benchmarks">this GitHub repository</a>.</p>
<ol>
<li>Modify constant declarations at the top of runner.php as appropriate (50 executions per test were used to get the results below), then execute it from the command line. It will in turn execute each of the scripts in the tests directory, measuring execution time and memory usage. Results will be recorded in results/raw.csv.</li>
<li>To generate graphs, run graphs.php. This uses the <a title="eZ Components - Documentation - Tutorials" href="http://ezcomponents.org/docs/tutorials/Graph">Graph component</a> from the <a title="eZ Components" href="http://ezcomponents.org/">ezComponents library</a>. Resulting images will be written to the results directory in PNG format.</li>
</ol>
<h4>Results</h4>
<table>
<tbody>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splfixedarray_eps.png" alt="SplFixedArray - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splfixedarray_memory.png" alt="SplFixedArray - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splfixedarray-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splfixedarray-array.php">Array</a><br />
<a title="tests/splfixedarray-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splfixedarray-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/spldoublylinkedlist_eps.png" alt="SplDoublyLinkedList - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/spldoublylinkedlist_memory.png" alt="SplDoublyLinkedList - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/spldoublylinkedlist-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/spldoublylinkedlist-array.php">Array</a><br />
<a title="tests/spldoublylinkedlist-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/spldoublylinkedlist-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splstack_eps.png" alt="SplStack - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splstack_memory.png" alt="SplStack - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splstack-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splstack-array.php">Array</a><br />
<a title="tests/splstack-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splstack-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splqueue_eps.png" alt="SplQueue - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splqueue_memory.png" alt="SplQueue - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splqueue-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splqueue-array.php">Array</a><br />
<a title="tests/splqueue-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splqueue-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splminheap_eps.png" alt="SplMinHeap - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splminheap_memory.png" alt="SplMinHeap - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splminheap-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splminheap-array.php">Array</a><br />
<a title="tests/splminheap-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splminheap-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splpriorityqueue_eps.png" alt="SplPriorityQueue - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splpriorityqueue_memory.png" alt="SplPriorityQueue - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splpriorityqueue-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splpriorityqueue-array.php">Array</a><br />
<a title="tests/splpriorityqueue-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splpriorityqueue-spl.php">SPL</a></td>
</tr>
<tr>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splobjectstorage_eps.png" alt="SplObjectStorage - Executions Per Second" width="400" height="225" /></td>
<td><img src="http://github.com/elazar/spl-benchmarks/raw/master/results/splobjectstorage_memory.png" alt="SplObjectStorage - Memory" width="400" height="225" /></td>
<td><strong>Code</strong><br />
<a title="tests/splobjectstorage-array.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splobjectstorage-array.php">Array</a><br />
<a title="tests/splobjectstorage-spl.php at master from elazar's spl-benchmarks - GitHub" href="http://github.com/elazar/spl-benchmarks/blob/master/tests/splobjectstorage-spl.php">SPL</a></td>
</tr>
</tbody>
</table>
<h3>Other Data Structures</h3>
<p>If you have an interest in other data structure implementations for PHP outside of SPL offerings, check out the <a title="PECL :: Package :: bloomy" href="http://pecl.php.net/package/bloomy">bloomy</a> <a title="PECL :: The PHP Extension Community Library" href="http://pecl.php.net/">PECL</a> extension, which is an implementation of a <a title="Bloom filter - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Bloom_filter">bloom filter</a> created by <a title="Bloom Filters Quickie - Andrei Zmievski" href="http://zmievski.org/2009/04/bloom-filters-quickie">Andrei Zmievski</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>New SPL Features in PHP 5.3 Webcast Slides</title>
		<link>http://matthewturland.com/2009/06/27/new-spl-features-in-php-53-webcast-slides/</link>
		<comments>http://matthewturland.com/2009/06/27/new-spl-features-in-php-53-webcast-slides/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 14:15:58 +0000</pubDate>
		<dc:creator>Matthew Turland</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Hope you were able to make it to the CodeWorks 2009 webcast at which I presented on New SPL Features in PHP 5.3! I&#8217;ve posted the slides and source code. I hope you enjoyed the webcast and that you&#8217;ll register for the excellent selection of upcoming webcasts leading up to CodeWorks 2009.]]></description>
			<content:encoded><![CDATA[<p>Hope you were able to make it to the <a href="http://cw.mtacon.com/main/news/view/22/Don_t_Miss_Tomorrow_s_Free_Webcast">CodeWorks 2009 webcast</a> at which I presented on New SPL Features in PHP 5.3! I&#8217;ve posted the <a href="http://www.slideshare.net/tobias382/new-spl-features-in-php-53">slides</a> and <a href="http://matthewturland.com/user/files/spl.tar.gz">source code</a>. I hope you enjoyed the webcast and that you&#8217;ll register for the <a href="http://cw.mtacon.com/main/news/view/19/php_architect_Launches_Summer_Webcast_Series">excellent selection of upcoming webcasts</a> leading up to CodeWorks 2009.</p>
]]></content:encoded>
			<wfw:commentRss>http://matthewturland.com/2009/06/27/new-spl-features-in-php-53-webcast-slides/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
