Start · Sprachen · PHP · Referenz · AppendIterator

AppendIterator

Klasse

Ermöglicht die sequentielle Iteration über mehrere angehängte Iteratoren, als wären sie eine einzige zusammenhängende Sequenz.

seit PHP 5.1.0 Kategorie: oop

Signatur

class AppendIterator extends IteratorIterator implements OuterIterator

Beschreibung

AppendIterator ist ein zusammengesetzter Iterator, dem beliebig viele weitere Iteratoren hinzugefügt werden können. Beim Durchlaufen werden alle angehängten Iteratoren nacheinander abgearbeitet – sobald der erste Iterator erschöpft ist, beginnt automatisch der nächste. So lassen sich mehrere Datenquellen (Arrays, Datenbankresultsets, Dateiobjekte usw.) zu einer einheitlichen Schleife zusammenfassen, ohne die Daten vorab in ein gemeinsames Array kopieren zu müssen.

Typische Anwendungsfälle sind das Zusammenführen von paginierten Ergebnissen, das Verarbeiten mehrerer Verzeichnisse oder das Verketten beliebiger Iteratoren in einer foreach-Schleife. Im Gegensatz zu einer manuellen Schleife über mehrere Arrays bleibt der Speicherbedarf gering, da die Daten lazy ausgewertet werden.

Über getArrayIterator() kann auf den internen ArrayIterator zugegriffen werden, der alle angehängten Iteratoren verwaltet. getInnerIterator() liefert den aktuell aktiven Iterator zurück, und getIteratorIndex() gibt den nullbasierten Index des gerade aktiven Iterators an.

Hinweis: Alle angehängten Iteratoren müssen das Iterator-Interface implementieren. Einfache Arrays müssen zuvor in ArrayIterator-Objekte gewrapptet werden.

Beispiele

Zwei ArrayIteratoren nacheinander durchlaufen

<?php
$fruits = new ArrayIterator(['Apfel', 'Banane', 'Kirsche']);
$veggies = new ArrayIterator(['Karotte', 'Brokkoli']);

$append = new AppendIterator();
$append->append($fruits);
$append->append($veggies);

foreach ($append as $key => $value) {
    echo "$key => $value\n";
}
0 => Apfel 1 => Banane 2 => Kirsche 0 => Karotte 1 => Brokkoli

Iterator-Index und aktiven Iterator ermitteln

<?php
$first  = new ArrayIterator([10, 20]);
$second = new ArrayIterator([30, 40]);
$third  = new ArrayIterator([50]);

$append = new AppendIterator();
$append->append($first);
$append->append($second);
$append->append($third);

foreach ($append as $value) {
    $iterIndex = $append->getIteratorIndex();
    echo "Iterator #{$iterIndex}: {$value}\n";
}
Iterator #0: 10 Iterator #0: 20 Iterator #1: 30 Iterator #1: 40 Iterator #2: 50

Mehrere Generatoren zusammenführen

<?php
function rangeGen(int $start, int $end): Generator {
    for ($i = $start; $i <= $end; $i++) {
        yield $i;
    }
}

$append = new AppendIterator();
$append->append(rangeGen(1, 3));
$append->append(rangeGen(10, 12));

foreach ($append as $val) {
    echo $val . ' ';
}
// Ausgabe: 1 2 3 10 11 12
1 2 3 10 11 12

// Wichtig · Fallstricke

Schlüssel-Kollisionen: Enthalten mehrere angehängte Iteratoren gleiche Schlüssel, werden diese beim Iterieren trotzdem ausgegeben – im Gegensatz zu Arrays, wo spätere Schlüssel frühere überschreiben würden. Dies kann bei der Auswertung von $key in foreach zu unerwarteten Duplikaten führen.

Rewind-Verhalten: Beim Aufruf von rewind() wird der erste angehängte Iterator zurückgesetzt; bereits verbrauchte Generatoren können dabei nicht erneut abgespielt werden – Generatoren sind nicht rewindbar.

Laufzeitänderungen: Das Hinzufügen weiterer Iteratoren via append() während einer laufenden Iteration ist möglich, aber mit Vorsicht zu verwenden, da es zu unerwartetem Verhalten führen kann.