Skip to content

PHP Tutorial Modern PHP Features

Iterables and Iterators

Lesson 232 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

You can loop over arrays with foreach. PHP also lets you loop over objects, as long as they are traversable.

The iterable type

iterable is a type that accepts an array or any Traversable object. It is handy for functions that only need to loop.

index.php
PHP
<?php
function printAll(iterable $items): void
{
    foreach ($items as $item) {
        echo $item . " ";
    }
}

printAll(["a", "b"]);
printAll(new ArrayIterator(["c", "d"]));
Output
OUTPUT
a b c d

IteratorAggregate: the easy way

The simplest way to make your own class loopable: implement IteratorAggregate and return an iterator from getIterator().

index.php
PHP
<?php
class Playlist implements IteratorAggregate
{
    private array $songs = [];

    public function add(string $song): void
    {
        $this->songs[] = $song;
    }

    public function getIterator(): Iterator
    {
        return new ArrayIterator($this->songs);
    }
}

$list = new Playlist();
$list->add("Sunrise");
$list->add("River");

foreach ($list as $i => $song) {
    echo ($i + 1) . ". $song\n";
}
Output
OUTPUT
1. Sunrise
2. River

The playlist keeps its data private, and foreach still works.

Iterator: full control

An Iterator implements five methods: current, key, next, rewind and valid. Use it when you need your own way of walking.

index.php
PHP
<?php
class Countdown implements Iterator
{
    private int $current;

    public function __construct(private int $from) {}

    public function rewind(): void { $this->current = $this->from; }
    public function valid(): bool { return $this->current > 0; }
    public function current(): int { return $this->current; }
    public function key(): int { return $this->from - $this->current; }
    public function next(): void { $this->current--; }
}

foreach (new Countdown(3) as $n) {
    echo $n . " ";
}
Output
OUTPUT
3 2 1

In practice, a generator (next lesson) is usually shorter.

Useful built-in functions

index.php
PHP
<?php
$it = new ArrayIterator(["x" => 1, "y" => 2]);

print_r(iterator_to_array($it));
echo iterator_count($it);
Output
OUTPUT
Array
(
    [x] => 1
    [y] => 2
)
2

iterator_to_array() turns any iterable into an array. iterator_count() counts the items. iterator_apply() calls a function for each.

Countable and ArrayAccess

Two more interfaces make a class feel like an array.

index.php
PHP
<?php
class Bag implements Countable, ArrayAccess
{
    private array $items = [];

    public function count(): int { return count($this->items); }
    public function offsetExists(mixed $offset): bool { return isset($this->items[$offset]); }
    public function offsetGet(mixed $offset): mixed { return $this->items[$offset] ?? null; }
    public function offsetSet(mixed $offset, mixed $value): void
    {
        if ($offset === null) {
            $this->items[] = $value;
        } else {
            $this->items[$offset] = $value;
        }
    }
    public function offsetUnset(mixed $offset): void { unset($this->items[$offset]); }
}

$bag = new Bag();
$bag[] = "apple";
$bag["fav"] = "mango";

echo count($bag) . " items, favourite: " . $bag["fav"];
Output
OUTPUT
2 items, favourite: mango

Where you meet them

  • Database result sets and collections in frameworks.
  • The Standard PHP Library (SPL): ArrayObject, SplStack, SplQueue, RecursiveDirectoryIterator.
  • Generators, covered next.
lightbulb
Choose the simplest
If a plain array does the job, use an array. Make a class traversable when you want to hide how the data is stored, or when the data is loaded lazily.