2010-09-21 19 views
9

he visto algo como esto en un ORM:¿Objeto que actúa como una matriz? (PHP)

$b = new Book(); 
    $b->limit(5)->get(); 

    echo 'ID: ' . $b->id . '<br />'; 
    echo 'Name: ' . $b->title . '<br />'; 
    echo 'Description: ' . $b->description . '<br />'; 
    echo 'Year: ' . $b->year . '<br />'; 

    foreach ($b as $book) 
    { 
     echo 'ID: ' . $book->id . '<br />'; 
     echo 'Name: ' . $book->title . '<br />'; 
     echo 'Description: ' . $book->description . '<br />'; 
     echo 'Year: ' . $book->year . '<br />'; 
     echo '<br />'; 
    } 

¿Cómo es posible que un objeto actúa como matriz y objeto? ¿Cómo puedo lograr eso? Tenía la esperanza de ver un nuevo método __magic o algo en la clase principal de Book, pero no pude encontrar nada, por lo que podría haber algo realmente básico sobre los objetos php que no conozco.

¿Alguna idea? Gracias de antemano

Respuesta

12

objetos que implementan la interfaz Traversable (a través de Iterator o IteratorAggregate) apoyar la construcción foreach, si eso es lo que entendemos por "actuar como una matriz." Por ejemplo:

class theClass implements Iterator { 
    // implement iterator here 
} 

// now you can do 
$obj = new theClass; 

foreach ($obj as $value) { 
    // do something 
} 
+1

Te va a encantar esto! :) – balupton

+0

sí, eso es lo que menciono, ¡gracias! –

+6

En realidad, todos los objetos se pueden tarar con foreach, pero accederá a todas las propiedades públicas.Necesita implementar 'Iterator' si desea cambiar este comportamiento. Otra interfaz en la que podría estar interesado es 'ArrayAccess' – Mchl

5

Usted no tiene que hacer nada especial para usar con objetos foreach.

Desde el PHP manual on Object Iteration:

PHP 5 ofrece una manera para que los objetos que se definen por lo que es posible iterar a través de una lista de elementos, con, por ejemplo, una instrucción foreach. Por defecto, todas las propiedades visibles se usarán para la iteración.

Ejemplo:

class Foo 
{ 
    public $foo = 1; 
    protected $bar = 2; 
    private $baz = 3; 
} 

foreach(new Foo as $prop) echo $prop; // outputs 1 only 

Su clase no tiene que poner en práctica Traversable como se sugiere en otro lugar y, de hecho, la clase anterior no:

var_dump (new Foo instanceof Traversable); // FALSE 

Usted puede implementar uno de Iterator o IteratorAggregate si necesita más control sobre cómo debe comportarse la iteración:

class Foo implements IteratorAggregate 
{ 
    public $foo = 1; 
    protected $bar = 2; 
    private $baz = 3; 

    public function getIterator() 
    { 
     return new ArrayIterator((array) $this); 
    } 
} 

foreach(new Foo as $prop) echo $prop; // outputs 123 

Debido Iterator y IteratorAggregate extienden Traversable, su clase de ahora también será una instancia de Traversable, pero como se muestra más arriba, no es necesario para la iteración el objeto.

var_dump (new Foo instanceof Traversable); // TRUE 

También puede utilizar un ArrayObject para que el objeto se comporta como un híbrido entre clase y objeto. O puede implementar ArrayAccess para permitir el acceso a la clase con corchetes. También puede subclase la clase que será one of the Iterators PHP.

Más información:

Cuestiones relacionadas