PHP.nl

Comparing generators with objects

Vergelijken van generators met Iterator-objecten

De belangrijkste voordelen van generators zijn hun eenvoud. Er hoeft veel minder boilerplate-code geschreven te worden in vergelijking met het implementeren van een klasse, en de code is over het algemeen veel leesbaarder. Bijvoorbeeld, de volgende functie en klasse zijn equivalent: Iterator

<?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('Couldn\'t open file "' . $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);
    }
}
?>

Deze flexibiliteit heeft echter een prijs: generators zijn forward-only iterators en kunnen niet worden teruggezet zodra de iteratie is begonnen. Dit betekent ook dat dezelfde generator niet meerdere keren kan worden doorlopen: de generator moet opnieuw worden opgebouwd door de generatorfunctie opnieuw aan te roepen.

Object Iteratie

Documentatie