PHP 5.5 was recently released, introducing several exciting new features to the language. In this article, we’ll go through some of the most interesting additions and discuss the benefits they provide to developers.
Generators
Generators are one of the most eagerly anticipated new features. They provide a way to handle iteration without having to write a class that implements the Iterator interface. Making a class conform to the Iterator interface requires a substantial amount of boilerplate code, so being able to avoid this by using generators can significantly reduce the size and complexity of code that developers must write.
Generators derive their functionality from the new yield keyword. A generator looks very similar to a normal function, but instead of returning a single value, a generator may yield any number of values.
To properly illustrate the power of generators, an example is needed. Consider PHP’s range() function, which returns an array of the values between the $start and $end arguments. We can use range() as follows:
<?php
foreach (range(0, 1000000) as $number) {
echo $number;
}
The problem in this example is that the array returned by range() will occupy a lot of memory (over 100mb according to the PHP manual). While the above code is a trivial demonstration, there are plenty of real-world situations where large arrays of data are constructed, often taking a long time to build and occupying a lot of memory.
With the introduction of generators, it’s now easy to tackle this problem without the inconvenience of having to write an Iterator class. Generators do not construct a large array, but rather return a single element at a time as they are iterated. Consider this modification to the above code, now using a generator to produce the range of values:
<?php
// define a simple range generator
function generateRange($start, $end, $step = 1) {
for ($i = $start; $i < $end; $i += $step) {
// yield one result at a time
yield $i;
}
}
foreach (generateRange(0, 1000000) as $number) {
echo $number;
}
This code produces exactly the same result as the first example, but without producing a large array to store all the values. According to the manual, this reduces the memory footprint to less than a single kilobyte – a huge saving compared with the original example.
No comments:
Post a Comment