Comparación de los generadores con los objetos Iterator

La principal ventaja de los generadores es su simplicidad. Menos código debe ser escrito que cuando se trata de implementar una clase Iterator, y generalmente es más legible. Por ejemplo, la función y la clase siguientes son equivalentes:

<?php
function getLinesFromFile($fileName) {
    if (!$fileHandle = fopen($fileName, 'r')) {
        return;
    }

    while (false !== $line = fgets($fileHandle)) {
        yield $line;
    }

    fclose($fileHandle);
}

// versus...

class LineIterator implements Iterator {
    protected $fileHandle;

    protected $line;
    protected $i;

    public function __construct($fileName) {
        if (!$this->fileHandle = fopen($fileName, 'r')) {
            throw new RuntimeException('Imposible abrir el fichero: "' . $fileName . '"');
        }
    }

    public function rewind() {
        fseek($this->fileHandle, 0);
        $this->line = fgets($this->fileHandle);
        $this->i = 0;
    }

    public function valid() {
        return false !== $this->line;
    }

    public function current() {
        return $this->line;
    }

    public function key() {
        return $this->i;
    }

    public function next() {
        if (false !== $this->line) {
            $this->line = fgets($this->fileHandle);
            $this->i++;
        }
    }

    public function __destruct() {
        fclose($this->fileHandle);
    }
}

Sin embargo, esta flexibilidad tiene un costo: los generadores son iteradores que solo avanzan, y no pueden ser reinicializados una vez que su recorrido haya comenzado. Esto también significa que el mismo generador no puede ser utilizado varias veces: el generador deberá ser reconstruido llamando nuevamente a la función generadora.

Ver también