← Back to PHP Course | Chapter 8: OOP | Lesson 13 of 14

PHP Iterator Interface

What Is the Iterator Interface?

PHP's built-in Iterator interface lets a custom object define exactly how it behaves inside a foreach loop, by implementing five specific methods. Without it, foreach only works on plain arrays and objects with public properties -- Iterator lets you control iteration over any internal data structure, including ones that aren't stored as a simple array.

Example: What Is the Iterator Interface?

php
<?php
class Numbers implements Iterator {
    private $items = [10, 20, 30];
    private $pos = 0;
    function current() { return $this->items[$this->pos]; }
    function key() { return $this->pos; }
    function next() { $this->pos++; }
    function rewind() { $this->pos = 0; }
    function valid() { return isset($this->items[$this->pos]); }
}
foreach (new Numbers() as $n) {
    echo $n . "\n";
}
?>

The Five Required Methods

current() returns the value at the current position, key() returns its key, next() advances the internal pointer, rewind() resets it to the start (called once, before the first iteration), and valid() returns a boolean telling foreach whether to keep looping. PHP calls these in a specific sequence automatically every time your object is used in a foreach.

Example: The Five Required Methods

php
<?php
class Numbers implements Iterator {
    private $items = [10, 20];
    private $pos = 0;
    function current() { return $this->items[$this->pos]; }
    function key() { return $this->pos; }
    function next() { $this->pos++; }
    function rewind() { $this->pos = 0; }
    function valid() { return isset($this->items[$this->pos]); }
}
$it = new Numbers();
$it->rewind();
while ($it->valid()) {
    echo $it->key() . ": " . $it->current() . "\n";
    $it->next();
}
?>

Implementing a Custom Iterator

A typical implementation wraps an internal array and an integer position pointer, delegating each interface method to simple operations on those two properties. This pattern lets you add validation, lazy computation, or filtering logic inside current() or valid() that a plain array could never do.

Example: Implementing a Custom Iterator

php
<?php
class EvenNumbers implements Iterator {
    private $items;
    private $pos = 0;
    function __construct($items) { $this->items = $items; }
    function current() { return $this->items[$this->pos]; }
    function key() { return $this->pos; }
    function next() { $this->pos++; }
    function rewind() { $this->pos = 0; }
    function valid() {
        return isset($this->items[$this->pos]) && $this->items[$this->pos] % 2 === 0;
    }
}
foreach (new EvenNumbers([2, 4, 6]) as $n) {
    echo $n . "\n";
}
?>

IteratorAggregate as a Shortcut

Implementing all five Iterator methods by hand is verbose when your class just wraps an existing array or object. IteratorAggregate requires only one method, getIterator(), which returns an Iterator (often an ArrayIterator wrapping your internal data) -- PHP delegates the actual iteration to whatever you return.

Example: IteratorAggregate as a Shortcut

php
<?php
class Collection implements IteratorAggregate {
    private $items = ["a", "b", "c"];
    function getIterator(): Iterator {
        return new ArrayIterator($this->items);
    }
}
foreach (new Collection() as $item) {
    echo $item . "\n";
}
?>

When to Use a Custom Iterator

Custom iterators matter when the underlying data isn't a plain array -- for example, iterating over database result rows one at a time without loading them all into memory, or walking a tree/linked-list structure in a defined traversal order. For a class that's just a thin wrapper around an array, IteratorAggregate with ArrayIterator is almost always simpler.

Example: When to Use a Custom Iterator

php
<?php
class SimpleList implements IteratorAggregate {
    private $items = [1, 2, 3];
    function getIterator(): Iterator {
        return new ArrayIterator($this->items);
    }
}
// A thin array wrapper is simpler with IteratorAggregate than a full Iterator
foreach (new SimpleList() as $item) {
    echo $item . "\n";
}
?>

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.