PHP 5 provee una forma para que los objetos a ser definidos puedan
interactuar a través de una lista de campos, con, por ejemplo una
sentencia foreach. Por
defecto, todas las propiedades visibles serán usadas para
la interacción.
Ejemplo 19-20. Simple interacción de un Objeto
<?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();
?>
|
El resultado del ejemplo seria:
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 se muestra en la salida, foreach interactúa
a través de todas la variables visibles que pueden ser
accesadas. Para dar un paso más allá, puede
implementar uno de las interfaces internas de PHP
llamada Iterator. Esto permite que el objeto
decida qué y como el objeto deba interactuar.
Ejemplo 19-21. Interacción de Objetos que implementan 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"; } ?>
|
El resultado del ejemplo seria:
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:
|
|
También puede definir la clase de tal manera que no necesita
definir todas la funciones del Iterator,
simplemente implementando la interface PHP 5
IteratorAggregate.
Ejemplo 19-22. Interacción de objetos que implementan IteratorAggregate
<?php class MyCollection implements IteratorAggregate { private $items = array(); private $count = 0;
// Required definition of 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"; } ?>
|
El resultado del ejemplo seria:
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:
|
|