Start · Sprachen · PHP · Referenz · NoRewindIterator

NoRewindIterator

Klasse

Kapselt einen Iterator und ignoriert alle <code>rewind()</code>-Aufrufe, sodass die Iteration immer an der aktuellen Position weiterläuft.

seit PHP 5.1.0 Kategorie: oop

Signatur

class NoRewindIterator extends IteratorIterator

Beschreibung

NoRewindIterator ist ein Wrapper-Iterator, der einen bestehenden Iterator aufnimmt und dessen rewind()-Methode unterdrückt. Das bedeutet: Egal wie oft rewind() aufgerufen wird (z. B. implizit durch eine foreach-Schleife), die interne Position des gekapselten Iterators wird nicht zurückgesetzt.

Das ist besonders nützlich, wenn eine große Datenquelle (z. B. ein Generator, ein Dateistream oder eine Datenbankabfrage) abschnittsweise in mehreren foreach-Schleifen verarbeitet werden soll, ohne von vorne zu beginnen. Ein Generator kann grundsätzlich nicht zurückgespult werden – NoRewindIterator macht dieses Verhalten explizit und verhindert so Laufzeitfehler.

Da NoRewindIterator von IteratorIterator erbt, implementiert er die Interfaces OuterIterator, Iterator und Traversable. Mit getInnerIterator() lässt sich der ursprüngliche Iterator zurückgewinnen.

Typische Einsatzfälle sind Streaming-Szenarien, bei denen Daten in Batches verarbeitet werden, oder wenn ein Iterator an mehrere Codestellen weitergegeben wird und jede Codestelle nahtlos dort weitermachen soll, wo die vorherige aufgehört hat.

Parameter

Name Typ Default Beschreibung
$iterator Pflicht Iterator Der zu kapselnde Iterator, dessen rewind()-Aufrufe fortan ignoriert werden.

Beispiele

Partielle foreach-Verarbeitung ohne Zurückspulen

<?php
function generateNumbers(): Generator {
    for ($i = 1; $i <= 6; $i++) {
        yield $i;
    }
}

$iterator = new NoRewindIterator(generateNumbers());

echo "Erste Hälfte:" . PHP_EOL;
$count = 0;
foreach ($iterator as $value) {
    echo $value . PHP_EOL;
    if (++$count === 3) {
        break;
    }
}

echo "Zweite Hälfte:" . PHP_EOL;
foreach ($iterator as $value) {
    // rewind() wird ignoriert – Iteration setzt bei 4 fort
    echo $value . PHP_EOL;
}
Erste Hälfte: 1 2 3 Zweite Hälfte: 4 5 6

Batch-Verarbeitung eines großen ArrayIterators

<?php
$data = new ArrayIterator(range(1, 10));
$noRewind = new NoRewindIterator($data);

$batchSize = 4;
$batch = 1;

while ($noRewind->valid()) {
    echo "Batch {$batch}:" . PHP_EOL;
    $count = 0;
    foreach ($noRewind as $value) {
        echo "  " . $value . PHP_EOL;
        if (++$count === $batchSize) {
            break;
        }
    }
    $batch++;
}
Batch 1: 1 2 3 4 Batch 2: 5 6 7 8 Batch 3: 9 10

// Wichtig · Fallstricke

Achtung: Wird NoRewindIterator direkt in einer foreach-Schleife ohne vorheriges break vollständig durchlaufen, ist der Iterator danach erschöpft. Eine weitere foreach-Schleife darüber liefert dann keine Elemente mehr, da rewind() keinen Effekt hat.

Bei Generatoren führt ein normaler rewind()-Aufruf nach dem ersten next() zu einer Exception. NoRewindIterator verhindert diesen Aufruf elegant, indem er ihn einfach ignoriert.

Die Methode getInnerIterator() liefert den ursprünglich übergebenen Iterator zurück und ermöglicht so den direkten Zugriff auf dessen aktuellen Zustand.