IteratorAggregate Arayüzü

(PHP 5, PHP 7, PHP 8)

Giriş

Harici bir yineleyici oluşturmak için arayüz.

Arayüz Sözdizimi

interface IteratorAggregate extends Traversable {
/* Yöntemler */
}

Örnekler

Örnek 1 - Temel kullanımı

<?php

class Verilerim implements IteratorAggregate
{
public
$özellik1 = "Birinci genel özellik";
public
$özellik2 = "İkinci genel özellik";
public
$özellik3 = "Üçüncü genel özellik";
public
$özellik4 = "";

public function
__construct()
{
$this->özellik4 = "son özellik";
}

/* PHP, tr_TR yerelinde bu yöntemi de arıyor, yoksa
* "Fatal error: Couldn't find implementation for method
* Verilerim::getiterator in Unknown on line 0"
* hatasını veriyor.
*/
public function getiterator()
{
return new
ArrayIterator($this);
}

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

$obj = new Verilerim();

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

?>

Yukarıdaki örnek şuna benzer bir çıktı üretir:

string(9) "özellik1"
string(22) "Birinci genel özellik"

string(9) "özellik2"
string(22) "İkinci genel özellik"

string(9) "özellik3"
string(25) "Üçüncü genel özellik"

string(9) "özellik4"
string(12) "son özellik"

İçindekiler

add a note

User Contributed Notes 5 notes

up
33
trumbull dot j at gmail dot com
8 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
22
Tab Atkins
13 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
11
Martin Speer
6 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
12
Lubaev.K
12 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
0
crimsonsaurer at gmail dot com
16 hours ago
With PHP 8.5, using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants. This means the example code above no longer functions. Luckily, there is an easy fix that only requires changing the return statement in the getIterator method. Below are two options for achieving the same functionality:
<?php
    public function getIterator(): Traversable
    {
        return new ArrayIterator(get_object_vars($this));
    }
?>

OR

<?php
    public function getIterator(): Traversable
    {
        yield from get_object_vars($this);
    }
?>
To Top