PHP 8.1.24 Released!

The IteratorAggregate interface

(PHP 5, PHP 7, PHP 8)

Introduction

Interface to create an external Iterator.

Interface synopsis

interface IteratorAggregate extends Traversable {
/* Methods */
}

Example #1 Basic usage

<?php
class myData implements IteratorAggregate {
public
$property1 = "Public property one";
public
$property2 = "Public property two";
public
$property3 = "Public property three";
public
$property4 = "";

public function
__construct() {
$this->property4 = "last property";
}

public function
getIterator(): Traversable {
return new
ArrayIterator($this);
}
}

$obj = new myData;

foreach(
$obj as $key => $value) {
var_dump($key, $value);
echo
"\n";
}
?>

The above example will output something similar to:

string(9) "property1"
string(19) "Public property one"

string(9) "property2"
string(19) "Public property two"

string(9) "property3"
string(21) "Public property three"

string(9) "property4"
string(13) "last property"

Table of Contents

add a note

User Contributed Notes 5 notes

up
26
trumbull dot j at gmail dot com
6 years ago
It might seem obvious, but you can return a compiled generator from your IteratorAggregate::getIterator() implementation.

<?php
class Collection implements IteratorAggregate
{
private
$items = [];

public function
__construct($items = [])
{
$this->items = $items;
}

public function
getIterator()
{
return (function () {
while(list(
$key, $val) = each($this->items)) {
yield
$key => $val;
}
})();
}
}

$data = [ 'A', 'B', 'C', 'D' ];
$collection = new Collection($data);

foreach (
$collection as $key => $val) {
echo
sprintf("[%s] => %s\n", $key, $val);
}
?>
up
23
Tab Atkins
11 years ago
Note that, at least as of 5.3, you still aren't allowed to return a normal Array from getIterator().

In some places, the docs wrap the array into an ArrayObject and return that. DON'T DO IT. ArrayObject drops any empty-string keys on the floor when you iterate over it (again, at least as of 5.3).

Use ArrayIterator instead. I wouldn't be surprised if it didn't have its own set of wonderful bugs, but at the very least it works correctly when you use it with this method.
up
15
Lubaev.K
10 years ago
<?php
// IteratorAggregate
// Create indexed and associative arrays.

class myData implements IteratorAggregate {

private
$array = [];
const
TYPE_INDEXED = 1;
const
TYPE_ASSOCIATIVE = 2;

public function
__construct( array $data, $type = self::TYPE_INDEXED ) {
reset($data);
while( list(
$k, $v) = each($data) ) {
$type == self::TYPE_INDEXED ?
$this->array[] = $v :
$this->array[$k] = $v;
}
}

public function
getIterator() {
return new
ArrayIterator($this->array);
}

}

$obj = new myData(['one'=>'php','javascript','three'=>'c#','java',], /*TYPE 1 or 2*/ );

foreach(
$obj as $key => $value) {
var_dump($key, $value);
echo
PHP_EOL;
}

// if TYPE == 1
#int(0)
#string(3) "php"
#int(1)
#string(10) "javascript"
#int(2)
#string(2) "c#"
#int(3)
#string(4) "java"

// if TYPE == 2
#string(3) "one"
#string(3) "php"
#int(0)
#string(10) "javascript"
#string(5) "three"
#string(2) "c#"
#int(1)
#string(4) "java"
?>

Good luck!
up
7
Martin Speer
4 years ago
You can use yield from in getIterator in recent PHP 7 versions:

<?php

class Example implements \IteratorAggregate
{
protected
$data = [];

public function
__construct(array $data)
{
$this->data = $data;
}

public function
getIterator()
{
yield from
$this->data;
}
}

$test = new Example([1, 2, 3]);

foreach (
$test as $node) {
echo
$test, PHP_EOL;
}

/*
* Outputs:
*
* 1
* 2
* 3
*/
?>
up
-14
ribeirocfb at gmail dot com
8 years ago
Example of the Iterator Pattern

<?php

namespace DesignPaterns;

class
BookCollection implements \IteratorAggregate
{
private
$a_titles = array();

public function
getIterator()
{
return new
BookIterator($this);
}

public function
addTitle($string)
{
$this->a_titles[] = $string;
}

public function
getTitle($key)
{
if (isset(
$this->a_titles[$key])){
return
$this->a_titles[$key];
}
return
null;
}

public function
is_empty()
{
return empty(
$a_titles);
}
}

<?
php

namespace DesignPaterns;

class
BookIterator implements \Iterator
{
private
$i_position = 0;
private
$booksCollection;

public function
__construct(BookCollection $booksCollection)
{
$this->booksCollection = $booksCollection;
}

public function
current()
{
return
$this->booksCollection->getTitle($this->i_position);
}

public function
key()
{
return
$this->i_position;
}

public function
next()
{
$this->i_position++;
}

public function
rewind()
{
$this->i_position = 0;
}

public function
valid()
{
return !
is_null($this->booksCollection->getTitle($this->i_position));
}
}

<?
php require 'vendor/autoload.php';

use
DesignPaterns\BookCollection;

$booksCollection = new BookCollection();
$booksCollection->addTitle('Design Patterns');
$booksCollection->addTitle('PHP7 is the best');
$booksCollection->addTitle('Laravel Rules');
$booksCollection->addTitle('DHH Rules');

foreach(
$booksCollection as $book){
var_dump($book);
}

/* === Output ===
* string(15) "Design Patterns"
* string(16) "PHP7 is the best"
* string(13) "Laravel Rules"
* string(9) "DHH Rules"
*/
To Top