PHP 5 предоставя възможност на обектите да бъдат дефинирани така, че да могат да бъдат итерирани, примерно с цикъл foreach. По подразбиране всички видими свойства ще бъдат използвани при итерирането.
Example #1 Просто итериране на обект
<?php
class MyClass
{
public $var1 = 'стойност 1';
public $var2 = 'стойност 2';
public $var3 = 'стойност 3';
protected $protected = 'protected променлива';
private $private = 'private променлива';
function iterateVisible() {
echo "MyClass::iterateVisible:\n";
foreach($this as $key => $value) {
print "$key => $value\n";
}
}
}
$class = new MyClass();
foreach($class as $key => $value) {
print "$key => $value\n";
}
echo "\n";
$class->iterateVisible();
?>
Примерът по-горе ще изведе:
var1 => стойност 1 var2 => стойност 2 var3 => стойност 3 MyClass::iterateVisible: var1 => стойност 1 var2 => стойност 2 var3 => стойност 3 protected => protected променлива private => private променлива
Както показва резултатът, цикълът foreach обхожда всички видими променливи, до които има достъп. Ако отидем една крачка по-напред, можем да реализираме един от вътрешните интерфейси на PHP 5 - Iterator. Реализирането на този интерфейс дава възможност на обекта сам да решава какво и как ще се итерира.
Example #2 Итериране на обект, реализиращ интерфейса Iterator
<?php
class MyIterator implements Iterator
{
private $var = array();
public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
}
public function rewind() {
echo "превъртане\n";
reset($this->var);
}
public function current() {
$var = current($this->var);
echo "текущ: $var\n";
return $var;
}
public function key() {
$var = key($this->var);
echo "ключ: $var\n";
return $var;
}
public function next() {
$var = next($this->var);
echo "следващ: $var\n";
return $var;
}
public function valid() {
$var = $this->current() !== false;
echo "валиден: {$var}\n";
return $var;
}
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $a => $b) {
print "$a: $b\n";
}
?>
Примерът по-горе ще изведе:
превъртане текущ: 1 валиден: 1 текущ: 1 ключ: 0 0: 1 следващ: 2 текущ: 2 валиден: 1 текущ: 2 ключ: 1 1: 2 следващ: 3 текущ: 3 валиден: 1 текущ: 3 ключ: 2 2: 3 следващ: текущ: валиден:
Можете да дефинирате вашия клас така, че да не се налага да дефинирате всички функции от интерфейса Iterator, като реализирате интерфейса IteratorAggregate в PHP 5.
Example #3 Итериране на обект, реализиращ IteratorAggregate
<?php
class MyCollection implements IteratorAggregate
{
private $items = array();
private $count = 0;
// Задължителен за дефиниране метод на интерфейса IteratorAggregate
public function getIterator() {
return new MyIterator($this->items);
}
public function add($value) {
$this->items[$this->count++] = $value;
}
}
$coll = new MyCollection();
$coll->add('стойност 1');
$coll->add('стойност 2');
$coll->add('стойност 3');
foreach ($coll as $key => $val) {
echo "ключ/стойност: [$key -> $val]\n\n";
}
?>
Примерът по-горе ще изведе:
превъртане текущ: стойност 1 валиден: 1 текущ: стойност 1 ключ: 0 ключ/стойност: [0 -> стойност 1] следващ: стойност 2 текущ: стойност 2 валиден: 1 текущ: стойност 2 ключ: 1 ключ/стойност: [1 -> стойност 2] следващ: стойност 3 текущ: стойност 3 валиден: 1 текущ: стойност 3 ключ: 2 ключ/стойност: [2 -> стойност 3] следващ: текущ: валиден:
Забележка: За повече примери относно итераторите погледнете Разширение SPL.