Forum und email

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 foreach . Por padrão, todas as propriedades visíveis serão usadas para a iteração.

Example#1 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.

Example#2 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.

Example#3 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.