Start · Sprachen · PHP · Referenz · Traversable

Traversable

Interface

Basis-Interface, das kennzeichnet, ob ein Objekt mit <code>foreach</code> durchlaufen werden kann.

seit PHP 5.0.0 Kategorie: misc

Signatur

interface Traversable

Beschreibung

Traversable ist ein internes PHP-Interface und dient als Marker, der anzeigt, dass ein Objekt mit der foreach-Schleife iterierbar ist. Es ist das Fundament der Iterator-Hierarchie in PHP und kann nicht direkt von eigenen Klassen implementiert werden – stattdessen müssen entweder Iterator oder IteratorAggregate implementiert werden, die beide von Traversable ableiten.

Das Interface selbst besitzt keine Methoden. Es ist ausschließlich dazu gedacht, als Typ-Hinweis (Type-Hint) genutzt zu werden, um sicherzustellen, dass ein übergebenes Objekt mit foreach durchlaufen werden kann – unabhängig davon, ob es Iterator, IteratorAggregate oder ein internes PHP-Objekt (z. B. SimpleXMLElement) ist.

Ab PHP 8.0 wird Traversable außerdem automatisch von iterable eingeschlossen. Der Pseudotyp iterable akzeptiert sowohl Arrays als auch Traversable-Objekte. In modernem PHP-Code empfiehlt es sich, iterable als Typ-Hinweis zu verwenden, wenn sowohl Arrays als auch traversierbare Objekte akzeptiert werden sollen.

  • Eigene Klassen implementieren Iterator für volle Kontrolle über die Iteration.
  • Eigene Klassen implementieren IteratorAggregate, um einen externen Iterator zu liefern.
  • Traversable eignet sich ideal als Typ-Hinweis in Funktionsparametern, wenn nur die Durchlaufbarkeit geprüft werden soll.

Beispiele

Traversable als Typ-Hinweis in einer Funktion

<?php
function printAll(Traversable $items): void {
    foreach ($items as $key => $value) {
        echo $key . ' => ' . $value . PHP_EOL;
    }
}

class NumberRange implements Iterator {
    private int $current;

    public function __construct(
        private int $start,
        private int $end
    ) {
        $this->current = $start;
    }

    public function current(): int  { return $this->current; }
    public function key(): int      { return $this->current - $this->start; }
    public function next(): void    { $this->current++; }
    public function rewind(): void  { $this->current = $this->start; }
    public function valid(): bool   { return $this->current <= $this->end; }
}

$range = new NumberRange(1, 3);
printAll($range);
0 => 1 1 => 2 2 => 3

Prüfen, ob ein Wert traversierbar ist

<?php
function isTraversable(mixed $value): string {
    if ($value instanceof Traversable) {
        return 'Traversable-Objekt';
    }
    if (is_array($value)) {
        return 'Array (kein Traversable, aber iterable)';
    }
    return 'Nicht iterierbar';
}

class MyCollection implements IteratorAggregate {
    private array $data = ['a', 'b', 'c'];

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

echo isTraversable(new MyCollection()) . PHP_EOL;
echo isTraversable(['x', 'y'])         . PHP_EOL;
echo isTraversable('hello')            . PHP_EOL;
Traversable-Objekt Array (kein Traversable, aber iterable) Nicht iterierbar

// Wichtig · Fallstricke

Direktes Implementieren nicht möglich: Der Versuch, Traversable direkt in einer eigenen Klasse zu implementieren (class Foo implements Traversable), führt zu einem fatalen Fehler. Stattdessen muss Iterator oder IteratorAggregate implementiert werden.

Typ-Hinweis vs. iterable: Traversable als Typ-Hinweis akzeptiert keine Arrays. Sollen Arrays und Traversable-Objekte gleichermaßen akzeptiert werden, ist der Pseudotyp iterable (verfügbar seit PHP 7.1) oder der Union-Type array|Traversable die bessere Wahl.

Interne Objekte: Viele interne PHP-Klassen wie SimpleXMLElement, DirectoryIterator oder PDOStatement sind ebenfalls Traversable, auch wenn sie Iterator nicht explizit im PHP-Userland implementieren.