Reputation: 2775
I know that this can be super easily archieved without generators, however I want to understand generators better. Therefore please don't suggest using something else.
I've got a class that generates filenames for screenshots (selenium):
class ScreenshotName
{
private $counter = 0;
public function screenshotNameIterator()
{
while(true) {
yield sprintf("screenshot-%s-%s.png", date("Y-m-d\\TH:i:s"), ++$this->counter);
}
}
}
Now my question is: can I use such a generator in any other context than a foreach loop? e.g.
(new ScreenshotName())->screenshotNameIterator()->next()
for me this always returns null, and if I debug, it never enters the generator method. Also the PHP docs don't really mention this.
So my question is: is there a documented way to use a generator in a different context than a for-loop?
Upvotes: 4
Views: 1793
Reputation: 21321
Here is a complete code snippet to go with Dark Duck's answer. That is, it demonstrates how to use Iterator interface to iterate over all values. (Dark Duck's code is not complete.) Based on a comment by robert_e_lee on Iterator doc:
$gen = evenNumbers();
// If in a method that re-uses an iterator, may want the next line.
//OPTIONAL $gen->rewind();
while ($gen->valid()) {
// This is the value:
$value = $it->current();
// You might or might not care about the key:
//OPTIONAL $key = $it->key();
// ... use $value and/or $key ...
$it->next();
}
The above is roughly equivalent to:
foreach (evenNumbers() as $value) {
// ... use $value ...
}
or
foreach (evenNumbers() as $key => $value) {
// ... use $value and/or $key ...
}
Upvotes: 0
Reputation: 1777
There is a documented way to do this. In fact Generator does implement the iterator interface as you can see it on this page.
In fact the foreach
keyword only work on iterators. So if you can use foreach
on a generator you must be able to call next
Here is a sample code using next
instead of foreach
:
<?php
function evenNumbers() {
for ($i = 0;; $i++) {
yield 2*$i;
}
}
$gen = evenNumbers();
$gen->next();
echo $gen->current();
?>
Upvotes: 2