(PHP 5, PHP 7, PHP 8)
Interface to create an external Iterator.
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"
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);
}
?>
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.
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
*/ ?>
<?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!