Die erste Verbesserung von Generatoren ist ihre Einfachheit. Viel weniger überladener Code muss geschrieben werden als im Vergleich zur Implementierung einer Iterator-Klasse und der Code ist generell einfacher zu lesen. Als Beispiel dienen folgende äquivalente Funktion und Klasse:
<?php
function leseZeilenVonDatei($dateiName) {
if (!$dateiHandle = fopen($dateiName, 'r')) {
return;
}
while (false !== $zeile = fgets($dateiHandle)) {
yield $zeile;
}
fclose($dateiHandle);
}
// im Gegensatz zu...
class LineIterator implements Iterator {
protected $dateiHandle;
protected $zeile;
protected $i;
public function __construct($dateiName) {
if (!$this->dateiHandle = fopen($dateiName, 'r')) {
throw new RuntimeException('Kann Datei "' . $dateiName . '" nicht öffnen');
}
}
public function rewind() {
fseek($this->dateiHandle, 0);
$this->zeile = fgets($this->dateiHandle);
$this->i = 0;
}
public function gueltig() {
return false !== $this->zeile;
}
public function aktuelle() {
return $this->zeile;
}
public function schluessel() {
return $this->i;
}
public function naechste() {
if (false !== $this->zeile) {
$this->zeile = fgets($this->dateiHandle);
$this->i++;
}
}
public function __destruct() {
fclose($this->dateiHandle);
}
}
?>
Diese Flexibilität kommt allerdings nicht ohne Preis: Generatoren sind forward-only-Iteratoren, und können nicht zurückgesetzt werden, wenn sie einmal gestartet wurden. Das heißt außerdem, dass der selbe Generator nicht mehrfach iteriert werden kann: der Generator muss entweder durch einen erneuten Aufruf der Funktion neu erstellt werden, oder muss durch das clone-Schlüsselwort geklont werden.