An iterator is an object that enables a programmer to traverse a container. Various types of iterators are often provided via a container’s interface.
// Create a DirectoryIterator to list all files in current directory.
$it = new DirectoryIterator('./');
foreach ($it as $file) {
// Excludes . and .. entries.
if (!$file->isDot()) {
echo $file->getFilename(), "\n";
}
}
All iterator objects in PHP must implement either the Iterator or the
IteratorAggregate interface. Iterator and IteratorAggregate both extend
the Traversable interface which is an abstract interface that can not be
implemented directly by any classes. Traversable itself has no methods
defined. The sole purpose of Traversable is to be used as dependency.
/*
* This function accepts both Iterator and IteratorAggregate as its parameter.
*/
function giveMeTraversable(Traversable $it)
{
// ...
}
Some built-in functions also require Traversable as parameters.
For example: iterator_count(), iterator_to_array().
Objects implementing Iterator act as the iterator itself, while objects
implementing IteratorAggregate act as a provider of Iterator. Both can be
used as an iterator.
The Iterator interface has 5 methods defined.
interface Iterator extends Traversable
{
public function current();
public function key();
public function next();
public function rewind();
public function valid();
}
While the IteratorAggregate interface has only 1 method.
interface IteratorAggregate extends Traversable
{
public function getIterator();
}
class IntegerRangeIterator implements Iterator
{
private $start;
private $end;
private $key;
private $value;
public function __construct($start, $end)
{
$this->start = (int)$start;
$this->end = (int)$end;
$this->rewind();
}
public function current()
{
return $this->value;
}
public function key()
{
return $this->key;
}
public function next()
{
if (!$this->valid()) {
return;
}
if ($this->value === $this->end) {
$this->value = null;
return;
}
if ($this->start < $this->end) {
$this->value++;
} else {
$this->value--;
}
$this->key++;
}
public function rewind()
{
$this->value = $this->start;
$this->key = 0;
}
public function valid()
{
return !is_null($this->value);
}
}
$it = new IntegerRangeIterator(10, 1);
foreach ($it as $key => $value) {
echo $key, ':', $value, "\n";
}
0:10
1:9
2:8
3:7
4:6
5:5
6:4
7:3
8:2
9:1
<?php
class IntegerRangeIterator implements IteratorAggregate
{
private $start;
private $end;
public function __construct($start, $end)
{
$this->start = (int)$start;
$this->end = (int)$end;
}
public function getIterator()
{
return new ArrayIterator(range($this->start, $this->end));
}
}
$it = new IntegerRangeIterator(1, 10);
foreach ($it as $key => $value) {
echo $key, ':', $value, "\n";
}
0:1
1:2
2:3
3:4
4:5
5:6
6:7
7:8
8:9
9:10
People often forget about the underused, built-in iterators in PHP’s standard PHP library.