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

PMG Digital Made for Humans

Making Traversable Interfaces the Right Way

2 MINUTE READ | April 21, 2015

Making Traversable Interfaces the Right Way

In PHP, objects that implement Traversable can be used in foreach loops. Traversable can’t be implemented directly in userland (pure PHP) code and instead Iterator or IteratorAggregate have to be used.

But what if you’re defining an interface that’s iterable as part of its contract? Should your interface extend Iterator or IteratorAggregate?

iterator_or_iteratorag.php

<?phpinterface Foo extends \Iterator{    // ...}interface Bar extends \IteratorAggregate{    // ...}

Neither. Instead interfaces should extend Traversable directly.

extend_traversable.php

<?phpinterface Spam extends \Traversable{    // ...}

Since interfaces should be, for the most part, role based the clients of an interface shouldn’t care that Iterator or IteratorAggregate is used. They just care that they can iterate over an object.

Extending Traversable means that it’s up to the implementing class to choose the best way to accomplish its iteration. Just like it should be.

To implement an interface that extends traversable, the implementing class’s implements declaration should include Iterator or IteratorAggregate. The trick here is the ordering: Iterator or IteratorAggregate must come first.

good_traversable.php

<?phpinterface Spam extends \Traversable{    // ...}final class Ham implements \IteratorAggregate, Spam{    public function getIterator()    {        return new \ArrayIterator(range(1, 10));    }}

Doing otherwise causes an error on PHP (but seems to work okay on HHVM).

bad_traversable.php

Stay in touch

Bringing news to you

Subscribe to our newsletter

<?phpinterface Spam extends \Traversable{    // ...}final class Ham implements Spam, \IteratorAggregate{    public function getIterator()    {        return new \ArrayIterator(range(1, 10));    }}


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

ALL POSTS