PHP 5.5 Generators and Drupal
PHP 5.5 introduces generator functions. Generator functions return an object that can be iterated over - often to be used with a foreach loop, for example:
function gen_one_to_three() {
for ($i = 1; $i <= 3; $i++) {
// Note that $i is preserved between yields.
yield $i;
}
}
$generator = gen_one_to_three();
foreach ($generator as $value) {
echo "$value\n";
}
Which will output:
123
(Example taken from php.net).
PHP calls the generator function when it needs values - when the generator yields a value the state of the generator is saved, so it can then be resumed when the next value is required. This can lead to significant performance boosts over creating an array which only exists to be looped over as less memory is needed.
There is more detail on http://codingexplained.com/coding/php/introduction-to-php-generators.
So how can this apply to Drupal …
A render array might look like...
$wrapper = array(
'#type' => 'container',
'#attributes' => array(
'class' => array('class'),
),
‘item-one’ = array ( … );
‘item-two’ = array ( … );
‘item-three’ = array ( … );
);
The element_children function returns an array which contains the array keys of the children array elements. This breaks from the standard PHP foreach pattern where you perform operations directly on the value created by the foreach loops - I don’t think this is ideal - I had to look twice to see what was happening the first time I saw it.
Using generators, you can use a more typical php pattern - the following is equivalent to the above.
foreach(element_children_generator($variables) as $key => &$element) {
...
$element[‘#example’] = ‘example’;
dpm($element);
...
}
As well as being a more typical PHP pattern, referencing the element within the loop is cleaner.
There are downsides to this approach too. A developer familiar with Drupal may have to look twice to see what is going on with the yield keyword. Obviously this can’t go into Drupal 7 Core (which supports php 5.2.5+), and I wouldn’t recommend it for Contrib either for the same reason.
However since PHP 5.3 and below is EOL I think this pattern is well worth adopting in your own projects with low risk.
Read morePHP 5.5 Generators and DrupalBy Chris | 12th September 2014