2011-04-25 14 views
7

En Zend Guía de inicio rápido aquí http://framework.zend.com/manual/en/learning.quickstart.create-model.html podemos ver:Php __get y __set métodos mágicos: ¿por qué los necesitamos aquí?

class Application_Model_Guestbook 
{ 
    protected $_comment; 
    protected $_created; 
    protected $_email; 
    protected $_id; 

    public function __set($name, $value); 
    public function __get($name); 


    public function setComment($text); 
    public function getComment(); 
... 

normalmente Creo mi captadores y definidores sin ningún método mágico. He visto esto en la guía rápida, y no entiendo por qué podemos necesitar esto.

¿Alguien puede ayudarme?

Muchas gracias

+7

Reduce escribir. Eso es. –

+0

Entonces, en el mismo lugar que normalmente hago: $ object-> setComment ('hello'), puedo hacer lo siguiente: __set ($ _ comment, 'hello'); ? Creo que esto no es a lo que te refieres, porque no estoy reduciendo el tipeo. Gracias de nuevo. – MEM

+3

no llamas '__get' y' __set' directamente. Usted acaba de hacer esto: '$ objeto -> _ comentario = 'hola';' –

Respuesta

10

Usted (generalmente) nunca llama __set o __get directamente. $foo->bar llamará $foo->__get('bar') automáticamente si bar no está visible y existe __get.

En el tutorial al que se ha vinculado, getter y setter se configuran para llamar automáticamente a las funciones get/set individuales apropiadas. Entonces, $foo->comment = 'bar' llamará indirectamente al $foo->setComment('bar'). Esto no es necesario ... es solo una conveniencia.

En otros casos, __get puede ser útil para crear lo que parece una variable de solo lectura.

1

existen las __get y __set métodos mágicos para DOS razones:

  1. De modo que usted no tiene que dedicar tiempo a crear métodos de descriptor de acceso de vainilla para todas sus propiedades .

  2. Para permitirle implementar la sobrecarga de propiedad.

Si tiene propiedades que necesitan un tratamiento especial, los métodos mágicos no son para usted. Sin embargo, si sus propiedades simplemente contienen datos y no hay dependencias, entonces no hay razón para NO usar los métodos mágicos.

+0

¿Puede proporcionar un escenario de comparación entre esos casos cuando usamos métodos mágicos y aquellos cuando no los usamos? (uno simple). gracias de nuevo. – MEM

+0

Honestamente creo que el manual de PHP hace un muy buen trabajo de explicar los métodos mágicos con ejemplos: http://us2.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members –

+0

I no estoy de acuerdo :(Desafortunadamente encontré esa documentación bastante confusa y dado que son muchos los conceptos que no se explican, suponen que solo los programadores experimentados pueden hablar sobre métodos mágicos. Quizás. Pero desde el punto de vista de un novato, es algo difícil. mi pregunta habría que me ayude a aclarar un poco. – MEM

1

Más adelante en el tutorial, puede modificar los métodos __get() y __set() para que pueda ver por qué están allí.

Tener un manejo mágico como este puede permitirle hacer algunas cosas interesantes, como incluso hacer propiedades de "solo lectura" y puede evitar que hinche su clase con una carga desordenada de getter/setters.

9

Si "crea sus propios" getters y setters, estará realizando dos funciones para cada propiedad: getPropname() y setPropname. Al utilizar el "método mágico" setter/getter de PHP, no se escriben métodos individuales para cada propiedad. Puede establecer/obtener propiedades como si fueran públicas. Dentro de las funciones de sobrecarga, agrega la lógica específica de cada propiedad. Ejemplo:

public function __set($name, $value) { 
switch ($name) { 
    case 'comments': 
    // do stuff to set comments 
    break; 
    case 'parent_user': 
    // do stuff to set parent user 
    break; 
} 
} 
public function __get($name) { 
switch ($name) { 
    case 'comments': 
    // do stuff to get comments 
    break; 
    case 'parent_user': 
    // do stuff to get parent user 
    break; 
} 
} 

Ahora se puede acceder mediante el uso de los comentarios $obj->comments a cualquier juego o conseguir.

Para lograr la funcionalidad anterior sin utilizar las sobrecargas, habría tenido que escribir 4 métodos diferentes en su lugar. Esto es realmente más acerca de la organización del código, tanto en términos del archivo real como en términos de crear una interfaz estandarizada para objetos dentro de un proyecto.

yo personalmente prefiero hacer lo que hace y escribir métodos distintos para cada propiedad que necesito un captador complejo/definidor. Para mí, está más claramente organizado, y hay una separación clara entre las propiedades "simples" de un objeto y las propiedades que tienen una mayor complejidad o relaciones de uno a muchos.

+0

Gracias por su respuesta detallada. – MEM

0

Vas a tener problemas cuando se ha utilizado __set y desea anular la funcionalidad colocador en una clase de niños. Vas a tener que copiar el código completo en __set y cambiar sólo la parte específica en lugar de simplemente sobrescribir una función específica colocador -> código redundante

Este problema puede evitarse llamando a los setter específica en __set (gracias a cHao para la propina).

Ejemplo:

class Foo1 { 
    protected $normal; 
    protected $special; 

    public function setSpecial($special) { 
     if ($special == isReallySpecial()) { 
     $this->special = $special; 
     } 
    } 

    public function __set($key, $value) { 
     switch ($key) { 
     case 'normal': 
      $this->normal = $value; 
      break; 
     case 'special': 
      $this->setSpecial($value); 
     } 
    } 
} 

class Foo2 extends Foo1 { 
    public function setSpecial($special) { 
     if ($special == isNotReallySpecial()) { 
     $this->special = $special; 
     } 
    } 
} 
+4

Nótese que en este caso, el '' __get' y métodos __set' probable que llame a la getter o setter, respectivamente, ya que están especificados, así En tal caso, tiene '$ obj-> property' y' $ obj -> {get | set} Property (...) 'que son consistentes, y este problema no existe. – cHao

Cuestiones relacionadas