Iterator or IteratorAggregate?
Fabien Potencier
June 24, 2010
In my last two posts, I talked about PHP iterators. Here is a quick tip on the same topic.
If you have ever used iterators in your code, you have probably implemented
the Iterator interface. Objects of a class that implements Iterator can be
iterated over with the foreach loop:
$foo = new Foo(); foreach ($foo as $key => $value) { // do something with $key and $value }
The Iterator interface has five simple methods that must be implemented:
class Foo implements Iterator { protected $attributes; public function rewind() { reset($this->attributes); } public function current() { return current($this->attributes); } public function key() { return key($this->attributes); } public function next() { return next($this->attributes); } public function valid() { return false !== current($this->attributes); } }
The IteratorAggregate interface is quite similar (both interfaces implement
Traversable) but creates an external Iterator. But when the iterator is based
on an array, creating an external Iterator for this array gives you a more concise
and more readable code:
class Foo implements IteratorAggregate { protected $attributes; public function getIterator() { return new ArrayIterator($this->attributes); } }




Discussion
If you implement Iterator and try to iterate the same object inside an existing iteration, you'll mess up your internal index.
With IteratorAggregate, you can return a new external iterator object for each iteration.
@jblotus: The two code examples are functionally identical. The point of the article is not to show how Iterators can be used. Fabien already wrote about that earlier. It's about making Traversable classes simpler, and easier to maintain.
foreach(array_keys($array) as $key){
...
}
to avoid duplicating the array.
I guess it all depends on what you're iterating over.