PHP 5.5 added a really nice feature: Generators.
Generators allow you to create a function that returns an list of items without having to create a (possibly very large) array first.
Here’s a simple “classic” generator example. Suppose you wanted to create a range
function (PHP provides this but humour me :))
Our naive implementation will simply take a start value, an end value and return the range as an array:
function myRange($start, $end){
$results = array();
for($x = $start; $x < $end; $x++){
$results[] = $x;
}
return $results;
}
This will work fine, however if you attempt to loop over a very large number
$num = 10000000;
foreach(myRange(1,$num) as $item){
echo $item."\n";
}
You’ll that the script hangs for a very long time and may end up dying with a memory error.
This is because the myRange
function will attempt to create an array with 10,000,000 entries and loop over that.
A generator will greatly decrease the amount of memory needed. To implement the generator we simply yield
every value we want to return:
function generatorRange($start, $end){
for($x = $start; $x < $end; $x++){
yield $x;
}
}
Now if we attempt to loop over using a very large number we find that, not only do we start getting results immediately but the memory usage is much lower.
$num = 10000000;
foreach(generatorRange(1,$num) as $item){
echo $item."\n";
}
This is because PHP only has to store the information about the current state of the generator rather than storing all 10,000,000 numbers.
Have a cool use for generators? Let me know..