Home arrow PHP arrow Page 4 - The Iterator Pattern

A Variant Iterator API - PHP

This article, the first of two parts, explains how to use the Iteratorpattern to manipulate any collection of objects. It is excerpted fromchapter eight of the book PHP|architect's Guide to PHP Design Patterns, written by Jason E. Sweat (PHP|architect, 2005; ISBN: 0973589825).

  1. The Iterator Pattern
  2. Extending Lendable
  3. Sample Code
  4. A Variant Iterator API
By: php|architect
Rating: starstarstarstarstar / 10
November 23, 2005

print this article



While the foregoing code is a complete implementation of the Iterator pattern as described by GoF, you may find the four-method API a bit cumbersome. If so, you can collapse next(), currentItem(), and isDone()into justnext()by having the latter either advance and return the current item fromthe collection or return false if the entire collection has beenprocessed.

Here's one way to write a test for this variation of the API:

  class IteratorTestCase extends UnitTestCase {
// ...
function TestMediaIteratorUsage() {
$it = $this->lib->getIterator('media')
$output = '';
while ($item = $it->next()) {
$output .= $item->name;
$this->assertEqual('name1name2name3', $output);

In the code above, notice the simplified control structure for looping. next() returns an object or false, allowing you to perform the assignment inside the while loop conditional.

The next few examples explore variations of the Iterator pattern using the smaller interface. As a convenience, change the Library::getIterator() method to a parameterized Factory so you can get either the four-method iterator or the two-method iterator (next() and reset()) from that single method.

  class Library {
// ...
function getIterator($type=false) {
switch (strtolower($type)) {
case 'media':
$iterator_class = 'LibraryIterator';
$iterator_class =  
return new $iterator_class($this->collection);

Here, Library::getIterator() now acceptsa parameter to select what kind of iterator to return. The default isLibraryGofIterator (so the existing tests still pass). Passing thestring media to the method creates and returns a LibraryIterator instead.

This is some code to implement LibraryIterator:

  class LibraryIterator {
protected $collection;
function __construct($collection) {
$this->collection = $collection;
function next() {
return next($this->collection);

Oops! The dreaded red bar! What happened to get the error "Equal expectation fails at character 4 with name1name2name3 and name2name3"? Somehow, the first iteration was skipped—that's a bug. To fix the error, return current() for the first call of the next()method.

  class LibraryIterator {
protected $collection;
protected $first=true;
function __construct($collection) {
$this->collection = $collection;
function next() {
if ($this->first) {
$this->first = false;
return current($this->collection);
return next($this->collection);

Presto! A green bar and a streamlined while loop iterator.

>>> More PHP Articles          >>> More By php|architect

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates


Dev Shed Tutorial Topics: