Start · Sprachen · PHP · Referenz · ClosedGeneratorException

ClosedGeneratorException

Klasse

Wird geworfen, wenn versucht wird, einen Wert von einem bereits geschlossenen <code>Generator</code>-Objekt abzurufen.

seit PHP 7.0.0 Kategorie: error

Signatur

class ClosedGeneratorException extends RuntimeException

Beschreibung

ClosedGeneratorException ist eine spezialisierte Laufzeit-Ausnahme, die PHP intern wirft, wenn auf einen Generator zugegriffen wird, der sich bereits im geschlossenen Zustand befindet. Ein Generator gilt als geschlossen, sobald er vollständig durchgelaufen ist, explizit mit Generator::getReturn() oder durch Garbage Collection beendet wurde oder wenn er delegiert war (yield from) und der delegierte Generator ebenfalls abgeschlossen ist.

Typischerweise tritt diese Ausnahme auf, wenn Generator::current(), Generator::send() oder Generator::throw() nach dem Ende des Generators aufgerufen werden, ohne vorher per Generator::valid() zu prüfen, ob der Generator noch aktiv ist. Sie erbt direkt von RuntimeException und kann daher mit einem regulären catch (RuntimeException $e)-Block abgefangen werden.

Um diese Ausnahme zu vermeiden, sollte man vor jedem Zugriff auf einen Generator dessen Zustand mit Generator::valid() prüfen oder den Zugriff in einen try/catch-Block kapseln. Besonders in delegierten Generatoren (yield from) und bei der Nutzung von Generator::getReturn() ist Vorsicht geboten, da letztere Methode selbst eine ClosedGeneratorException auslösen kann, wenn der Generator noch nicht abgeschlossen ist.

Beispiele

ClosedGeneratorException beim Zugriff auf geschlossenen Generator

<?php
function meinGenerator(): Generator {
    yield 1;
    yield 2;
}

$gen = meinGenerator();

// Generator vollständig durchlaufen
foreach ($gen as $value) {
    echo $value . PHP_EOL;
}

// Generator ist nun geschlossen — Zugriff löst Ausnahme aus
try {
    $gen->send(42);
} catch (ClosedGeneratorException $e) {
    echo 'Fehler: ' . $e->getMessage() . PHP_EOL;
}
1 2 Fehler: Cannot rewind a generator that was already run

Sicherer Zugriff mit valid()-Prüfung

<?php
function zaehler(int $bis): Generator {
    for ($i = 1; $i <= $bis; $i++) {
        yield $i;
    }
}

$gen = zaehler(3);

while ($gen->valid()) {
    echo $gen->current() . PHP_EOL;
    $gen->next();
}

// Kein Zugriff mehr, daher keine ClosedGeneratorException
echo 'Generator sauber beendet.' . PHP_EOL;

// Rückgabewert nach ordnungsgemäßem Abschluss abrufen
try {
    $rueckgabe = $gen->getReturn();
    echo 'Rückgabewert: ' . var_export($rueckgabe, true) . PHP_EOL;
} catch (ClosedGeneratorException $e) {
    echo 'Kein Rückgabewert verfügbar: ' . $e->getMessage() . PHP_EOL;
}
1 2 3 Generator sauber beendet. Rückgabewert: NULL

// Wichtig · Fallstricke

Fallstrick: Generator::getReturn() wirft eine ClosedGeneratorException, wenn der Generator noch nicht abgeschlossen ist — also genau das Gegenteil der üblichen Fälle. Die Methode darf ausschließlich aufgerufen werden, wenn Generator::valid() false zurückgibt.

Da ClosedGeneratorException von RuntimeException erbt, wird sie auch von allgemeineren catch-Blöcken für RuntimeException oder Exception erfasst. Für eine präzise Fehlerbehandlung empfiehlt sich die explizite Verwendung von catch (ClosedGeneratorException $e).