This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.

PMG Digital Made for Humans

Generators & Iterator Aggregate: A Match Made in PHP Heaven

2 MINUTE READ | January 26, 2016

Generators & Iterator Aggregate: A Match Made in PHP Heaven


PHP added generators in version 5.5. You see them in code with the yield keyword and they tend to be used most often to iterate over a collection dynamically without creating it in memory all at once. Really you can do all sorts of fun things with generators that we’re not going to touch here.

IteratorAggregate has been around forever — since PHP 5.0. It’s a way to make an object traversable (able to be used in a foreach loop) without having to implement all the methods of Iterator.

also makes it possible to do nested loops on the same object.

A powerful combination is to use a generator within your IteratorAggregate::getIterator implementation. Rather than returning a new iterator object each time, just supply a generator. Here’s a small example.


<?phpclass MultiplyingIterator implements \IteratorAggregate{    /**     * @var array|Traversable     */    private $wrapped;    private $factor;    public function __construct($wrapped, $factor)    {        // will break if wrapped is a generator        // in the real world we'd type check this        $this->wrapped = $wrapped;        $this->factor = $factor;    }    public function getIterator()    {        foreach ($this->wrapped as $item) {            yield $item => $item * $this->factor;        }    }}

And it’s usage:


<?php$iter = new MultiplyingIterator([1, 2, 3, 4], 2);foreach ($iter as $orig => $changed) {    echo $orig, ': ', $changed, PHP_EOL;    foreach ($iter as $orig => $changed) {        echo '  inner ', $orig, ': ', $changed, PHP_EOL;    }}

This is an extremely powerful pattern when you need to iterate over collections with some form of known computation mixed in. Our recently released CSV library does this to produce associative arrays from a CSV file.

Something more dynamic would be better suited to a generic map implementation.


Stay in touch

Bringing news to you

Subscribe to our newsletter

<?phpfunction map(callable $cb, $collection) {    foreach ($collection as $key => $item) {        yield $item => $cb($item);    }}

Posted by Christopher Davis

Related Content

thumbnail image

Get Informed

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

Get Informed

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

Get Informed

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

Get Informed

Trading Symfony’s Form Component for Data Transfer Objects

8 MINUTES READ | September 3, 2019

Get Inspired

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

Get Informed

Parsing Redshift Logs to Understand Data Usage

7 MINUTES READ | May 6, 2019

Get Inspired

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Get Informed

Testing React

13 MINUTES READ | March 12, 2019

Get Inspired

Tips for Designing & Testing Software Without a UX Specialist

4 MINUTES READ | March 6, 2019

Get Informed

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018