Iteração de Objetos

PHP 5 fornece uma maneira de defini objetos para que seja possível iterar por uma lista de items, com, por exeplo, uma instrução a seção foreach Capítulo 16 . Por padrão, todas as propriedades visíveis serão usadas para a iteração.

Exemplo 19-21. Simple Object Iteration

<?php
class MyClass
{
    
public $var1 = 'value 1';
    
public $var2 = 'value 2';
    
public $var3 = 'value 3';

    
protected $protected = 'protected var';
    
private   $private   = 'private var';

    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();

?>

O exemplo acima irá imprimir:

var1 => value 1
var2 => value 2
var3 => value 3

MyClass::iterateVisible:
var1 => value 1
var2 => value 2
var3 => value 3
protected => protected var
private => private var

Como a saída mostra, o foreach iteragiu por cada uma das variáveis visíveis que podem ser acessadas. Indo um pouco mais longe, você pode implementar uma das interfaces internas do PHP5 chamada Iterator. Isso permite que o objeto decida o que e como o objeto será iterado.

Exemplo 19-22. Iteração de Objeto implmentando Iterator

<?php
class MyIterator implements Iterator
{
  
private $var = array();

  
public function __construct($array)
  {
    if (
is_array($array) ) {
      
$this->var = $array;
    }
  }

  
public function rewind() {
    echo
"rewinding\n";
    
reset($this->var);
  }

  
public function current() {
    
$var = current($this->var);
    echo
"current: $var\n";
    return
$var;
  }

  
public function key() {
    
$var = key($this->var);
    echo
"key: $var\n";
    return
$var;
  }

  
public function next() {
    
$var = next($this->var);
    echo
"next: $var\n";
    return
$var;
  }

  
public function valid() {
    
$var = $this->current() !== false;
    echo
"valid: {$var}\n";
    return
$var;
  }
}

$values = array(1,2,3);
$it = new MyIterator($values);

foreach (
$it as $a => $b) {
  print
"$a: $b\n";
}
?>

O exemplo acima irá imprimir:

rewinding
current: 1
valid: 1
current: 1
key: 0
0: 1
next: 2
current: 2
valid: 1
current: 2
key: 1
1: 2
next: 3
current: 3
valid: 1
current: 3
key: 2
2: 3
next:
current:
valid:

Você também pode definir sua classe para que ela não tenha que definir todas as funções do Iterator simplesmente implementado a interface IteratorAggregate do PHP 5.

Exemplo 19-23. Iteração de Objeto implementado IteratorAggregate

<?php
class MyCollection implements IteratorAggregate {
  
private $items = array();
  
private $count = 0;

  
/* Definião requirida da interface IteratorAggregate */
  
public function getIterator() {
    return new
MyIterator($this->items);
  }

  
public function add($value) {
    
$this->items[$this->count++] = $value;
  }

}

$coll = new MyCollection();
$coll->add('value 1');
$coll->add('value 2');
$coll->add('value 3');

foreach (
$coll as $key => $val) {
  echo
"key/value: [$key -> $val]\n\n";
}
?>

O exemplo acima irá imprimir:

rewinding
current: value 1
valid: 1
current: value 1
key: 0
key/value: [0 -> value 1]

next: value 2
current: value 2
valid: 1
current: value 2
key: 1
key/value: [1 -> value 2]

next: value 3
current: value 3
valid: 1
current: value 3
key: 2
key/value: [2 -> value 3]

next:
current:
valid:

Nota: Para mais exemplos de iteração, veja a Extensão SPL.