Generatoren
PHP Manual

Generator Syntax

Eine Generator Funktion sieht genau so aus wie eine normale Funktion mit Ausnahme, dass nicht ein Wert zurückgeliefert wird, sondern ein Generator liefert so viele Werte zurück, wie nötig sind (Stichwort: yield).

Wenn eine Generator Funktion aufgerufen wird, wird ein Objekt zurück geliefert. Wenn Sie über dieses Objekt iterieren (zum Beispiel, via einer foreach Schleife), wird PHP die Generator Funktion so oft aufrufen, wie Werte benötigt werden, dann wird der Status des Generators gesichert, so dass fortgefahren werden kann, wenn der nächste Wert benötigt wird.

Sobald keine weiteren Werte zurückgeliefert werden können, kann die Generator Funktion einfach beendet werden, und der rufende Code wird fortgesetzt als gäbe es keine weiteren Werte in einem Array.

Hinweis:

Ein Generator kann keine Werte zurückliefern: macht man dies, wird ein Kompilierungs Fehler zurückgeliefert. Eine leere return Anweisung ist eine gültige Syntax innerhalb eines Generators und wird den Generator beenden.

yield Schlüsselwort

Das Herz einer Generator Funktion ist das yield Schlüsselwort. In seiner einfachsten Form sieht das yield Schlüsselwort wie eine return Anweisung aus, ausser dass die Ausführung mit der Rückgabe nicht beendet wird, sondern yield vielmehr einen Wert für den Code bereitstellt über den der Generator schleift, und solange die Generator Funktion pausiert.

Beispiel #1 Ein einfaches Beispiel zum produzieren (yielding) von Werten

<?php
function generiere_eins_bis_drei() {
    for (
$i 1$i <= 3$i++) {
        
// Hinweis: $i bleibt zwischen den yields erhalten.
        
yield $i;
    }
}

$generator generiere_eins_bis_drei();
foreach (
$generator as $wert) {
    echo 
"$wert\n";
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

1
2
3

Hinweis:

Intern werden sequentielle integer Schlüssel mit den produzieren Werten verknüpft, so wie mit einem nicht-assoziativem array.

Achtung

Wenn Sie yield in einem Anweisungs Kontext nutzen (beispielsweise auf der rechten Seite einer Zuweisung), dann müssen Sie die yield Anweisung innerhalb von Klammern schreiben. Beispielsweise ist folgender Befehl gültig:

$daten = (yield $wert);

und diese Beispiel ist nicht gültig, und wird mit einen parse Fehler beendet:

$daten = yield $wert;

Diese Syntax wird in logischen UND-Funktionen bei der Generator::send() Methode genutzt.

Produzieren von Werten mit Schlüsseln

PHP unterstützt ebenfalls assoziative Arrays, und Generatoren unterscheiden sich nicht davon. Als Ergänzung einfacher produzierter Werte, wie oben gezeigt, können Sie zur gleichen Zeit auch einen Schlüssel zurückliefern.

Die Syntax für das produzieren eines Schlüssel/Wert Paares ist sehr ähnlich wie die Definition von assoziativen Arrays. Siehe unten.

Beispiel #2 Produzieren eines Schlüssel/Wert Paares

<?php
/*
 * Die Eingabe sind Semikolon getrennte Felder, mit dem ersten Feld
 * welches als ID und Schlüssel genutzt wird.
 */

$eingabe = <<<'EOF'
1;PHP;mag Dollar Zeichen
2;Python;mag Leerzeichen
3;Ruby;mag Blöcke
EOF;

function 
eingabe_parser($eingabe) {
    foreach (
explode("\n"$eingabe) as $zeile) {
        
$felder explode(';'$zeile);
        
$id array_shift($felder);

        
yield $id => $felder;
    }
}

foreach (
eingabe_parser($eingabe) as $id => $felder) {
    echo 
"$id:\n";
    echo 
"    $felder[0]\n";
    echo 
"    $felder[1]\n";
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

1:
    PHP
    mag Dollar Zeichen
2:
    Python
    mag Leerzeichen
3:
    Ruby
    mag Blöcke
Achtung

Wie oben gezeigt mit dem zurückliefern einfacher Werte, muss man beim produzieren eines Schlüssel/Wert Paares im Zuweisungs Kontext den yield Befehl einklammern:

$daten = (yield $schluessel => $wert);

Produzieren von null Werten

Yield kann ohne ein Argument aufgerufen werden, um ein NULL Wert mit einem automatischen Schlüssel zurückzuliefern.

Beispiel #3 Produzieren von NULLs

<?php
function generiere_drei_nulls() {
    foreach (
range(13) as $i) {
        
yield;
    }
}

var_dump(iterator_to_array(generiere_drei_nulls()));
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

array(3) {
  [0]=>
  NULL
  [1]=>
  NULL
  [2]=>
  NULL
}

Produzieren durch Referenzen

Generator Funktionen sind genauso in der Lage Werte durch Referenzen zurückzuliefern wie durch Werte. Dies kann in gleicher weise erfolgen wie zurückliefern von Referenzen aus Funktionen: dies geschieht durch voranstellen eines kaufmännisches Unds zum Funktionsnamen.

Beispiel #4 Produzieren von Werten durch Referenzen

<?php
function &generiere_referenz() {
    
$wert 3;

    while (
$wert 0) {
        
yield $wert;
    }
}

/*
 * Hinweis: wir können $nummer innerhalb der Schleife ändern, und
 * weil der Generator Referenzen zurückliefert, wird $wert
 * innerhalb von generiere_referenz() verändert.
 */
foreach (generiere_referenz() as &$nummer) {
    echo (--
$nummer).'... ';
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

2... 1... 0... 

Generator Objekte

Beim ersten Aufruf einer Generator Funktion wird ein Objekt der internen Generator Klasse zurückgeliefert. Dieses Objekt implementiert das Iterator Interface in gleicher weise wie es ein forward-only iterator Objekt machen würde.


Generatoren
PHP Manual