Iteración de objetos

PHP 5 ofrece una manera para definir objetos, por lo que es posible recorrer una lista de elementos con, por ejemplo, una sentencia foreach. Por defecto, se utilizarán todas las propiedades visibles para la iteración.

Ejemplo #1 Iteración simple de un objeto

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

protected
$protected = 'variable protegida';
private
$private = 'variable privada';

function
iterateVisible() {
echo
"MiClase::iterateVisible:\n";
foreach (
$this as $clave => $valor) {
print
"$clave => $valor\n";
}
}
}

$clase = new MiClase();

foreach(
$clase as $clave => $valor) {
print
"$clave => $valor\n";
}
echo
"\n";


$clase->iterateVisible();

?>

El resultado del ejemplo sería:

 var1 => valor 1 var2 => valor 2 var3 => valor 3 MiClase::iterateVisible: var1 => valor 1 var2 => valor 2 var3 => valor 3 protected => variable protegida private => variable privada 

Como se muestra en la salida, foreach recorre todas las propiedades visibles a las que se pueden acceder.

Para dar un paso más, se puede implementar la interfazIterator. Esto permite al objeto decidir cómo será iterado y qué valores estarán disponibles en cada iteración.

Ejemplo #2 Iteración de un objeto implementando Iterator

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

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

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

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

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

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

public function
valid()
{
$clave = key($this->var);
$var = ($clave !== NULL && $clave !== FALSE);
echo
"válido: $var\n";
return
$var;
}

}

$valores = array(1,2,3);
$it = new MiIterador($valores);

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

El resultado del ejemplo sería:

 rebobinando válido: 1 actual: 1 clave: 0 0: 1 siguiente: 2 válido: 1 actual: 2 clave: 1 1: 2 siguiente: 3 válido: 1 actual: 3 clave: 2 2: 3 siguiente: válido: 

La interfazIteratorAggregate se puede usar como alternativa para implementar todos los métodos de Iterator. IteratorAggregate solamente requiere la implementación de un único método, IteratorAggregate::getIterator(), el cual debería devolver una instancia de una clase que implemente Iterator.

Ejemplo #3 Iteración de un objeto implementando IteratorAggregate

<?php
class MiColección implements IteratorAggregate
{
private
$items = array();
private
$cuenta = 0;

// Se requiere la definición de la interfaz IteratorAggregate
public function getIterator() {
return new
MiIterador($this->items);
}

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

$colección = new MiColección();
$colección->add('valor 1');
$colección->add('valor 2');
$colección->add('valor 3');

foreach (
$colección as $clave => $val) {
echo
"clave/valor: [$clave -> $val]\n\n";
}
?>

El resultado del ejemplo sería:

 rebobinando actual: valor 1 válido: 1 actual: valor 1 clave: 0 clave/valor: [0 -> valor 1] siguiente: valor 2 actual: valor 2 válido: 1 actual: valor 2 clave: 1 clave/valor: [1 -> valor 2] siguiente: valor 3 actual: valor 3 válido: 1 actual: valor 3 clave: 2 clave/valor: [2 -> valor 3] siguiente: actual: válido: 

Nota:

Para más ejemplos de iteradores, véase la extensión SPL.

Nota:

Los usuarios de PHP 5.5 y posteriores pueden investigar los generadores, los cuales posibilitan una forma alternativa de definir iteradores.

To Top