dismiss Step into the future! Click here to switch to the beta php.net site
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | conferences | my php.net

search for in the

References Explained> <Generator syntax
[edit] Last updated: Fri, 04 Oct 2013

view this page in

Comparing generators with Iterator objects

The primary advantage of generators is their simplicity. Much less boilerplate code has to be written compared to implementing an Iterator class, and the code is generally much more readable. For example, the following function and class are equivalent:

<?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->fileHandle0);
        
$this->line fgets($this->fileHandle);
        
$this->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);
    }
}
?>

This flexibility does come at a cost, however: generators are forward-only iterators, and cannot be rewound once iteration has started. This also means that the same generator can't be iterated over multiple times: the generator will need to either be rebuilt by calling the generator function again, or cloned via the clone keyword.



References Explained> <Generator syntax
[edit] Last updated: Fri, 04 Oct 2013
 
add a note add a note User Contributed Notes Comparing generators with Iterator objects - [3 notes]
up
6
mNOSPAMsenghaa at nospam dot gmail dot com
3 months ago
This hardly seems a fair comparison between the two examples, size-for-size. As noted, generators are forward-only, meaning that it should be compared to an iterator with a dummy rewind function defined. Also, to be fair, since the iterator throws an exception, shouldn't the generator example also throw the same exception? The code comparison would become more like this:

<?php
function getLinesFromFile($fileName) {
    if (!
$fileHandle = fopen($fileName, 'r')) {
        throw new
RuntimeException('Couldn\'t open file "' . $fileName . '"');
    }
 
    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() { }
 
    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);
    }
}
?>

The generator is still obviously much shorter, but this seems a more reasonable comparison.
up
1
sou at oand dot re
3 months ago
I think to be more similar the samples in the function, throw a new exception is better. But looking into "Generator syntax" session, you can see there this: "An empty return statement is valid syntax within a generator and it will terminate the generator.". By this point of view, we can imagine that this is just to exemplify an usage of the empty return.
up
-3
user at instance dot com
3 months ago
"the following function and class are equivalent"
Why?
How do i get the current key when i use the generator?
How to rewind?
What if we do this?:
while($infileFilePath=getLinesFromFile($fileName1)){
  while($subInfileFilePath=getLinesFromFile($infileFilePath)){
      echo $subInfileFilePath;
  }
}
# note: $fileHandle is set when calling second time 'getLinesFromFile'?

Just do : $lines = file($fileName1);
and please make an real example
or explain it more  ...  thnx

 
show source | credits | stats | sitemap | contact | advertising | mirror sites