metodos magicos __tostring __set php magic-function

php - magicos - public function__ get



¿Cuándo debo/debo usar__construct(),__get(),__set() y__call() en PHP? (10)

Una pregunta similar trata de __construct , pero la dejé en mi título para las personas que buscan esta búsqueda.

Aparentemente, __get y __set toman un parámetro que es la variable que se obtiene o establece. Sin embargo, debe conocer el nombre de la variable (por ejemplo, saber que la edad de la persona es $ age en lugar de $ myAge). Por lo tanto, no veo el punto si TIENE que saber un nombre de variable, especialmente si está trabajando con un código con el que no está familiarizado (como una biblioteca).

Encontré algunas páginas que explican __get() , __set() y __call() , pero todavía no entiendo por qué o cuándo son útiles.


Otra aplicación útil de los métodos mágicos, especialmente __get y __set y __toString son plantillas. Puede hacer que su código sea independiente del motor de plantilla simplemente escribiendo un adaptador simple que use métodos mágicos. En caso de que desee pasar a otro motor de plantillas, solo cambie estos métodos.

class View { public $templateFile; protected $properties = array(); public function __set($property, $value) { $this->properties[$property] = $value; } public function __get($property) { return @$this->properties[$property]; } public function __toString() { require_once ''smarty/libs/Smarty.class.php''; $smarty = new Smarty(); $smarty->template_dir = ''view''; $smarty->compile_dir = ''smarty/compile''; $smarty->config_dir = ''smarty/config''; $smarty->cache_dir = ''smarty/cache''; foreach ($this->properties as $property => $value) { $smarty->assign($property, $value); } return $smarty->fetch($this->templateFile); } }

El beneficio oculto de este enfoque es que puedes anidar View objects uno dentro de otro:

$index = new View(); $index->templateFile = ''index.tpl''; $topNav = new View(); $topNav->templateFile = ''topNav.tpl''; $index->topNav = $topNav;

Y en index.tpl , el anidamiento se ve así:

<html> <head></head> <body> {$topNav} Welcome to Foobar Corporation. </body> </html>

Todos los objetos de Vista anidados se convierten en cadenas (HTML para ser exactos) sobre la marcha, tan pronto como se haga echo $index;


Probablemente no sea el diseño más limpio del mundo, pero tuve una situación en la que tenía una gran cantidad de código que hacía referencia a una variable de instancia en una clase, es decir:

$obj->value = ''blah''; echo $obj->value;

pero luego, quería hacer algo especial cuando se establecía "valor" bajo ciertas circunstancias, así que cambié el nombre de la variable de valor e implementé __set () y __get () con los cambios que necesitaba.

El resto del código no sabía la diferencia.


Son para hacer cosas "inteligentes".

Por ejemplo, podría usar __set() y __get() para hablar con una base de datos. Su código sería entonces: $myObject->foo = "bar"; y esto podría actualizar un registro de la base de datos detrás de escena. Por supuesto, tendrías que ser muy cuidadoso con esto o tu rendimiento podría sufrir, de ahí las citas de "inteligente" :)


Una buena razón para usarlos sería en términos de un sistema de registro (creo que Zend Framework lo implementa como un registro o una clase de configuración iirc), por lo que puedes hacer cosas como

$conf = new Config(); $conf->parent->child->grandchild = ''foo'';

Cada una de esas propiedades es un objeto de configuración generado automáticamente, algo similar a:

function __get($key) { return new Config($key); }

Obviamente, si $ conf-> parent ya existía, no se llamaría al método __get (), por lo que usarlo para generar nuevas variables es un buen truco.

Tenga en cuenta que este código que acabo de citar no es funcional, simplemente lo escribí rápidamente por ejemplo.


__get (), __set () y __call () son lo que PHP llama "métodos mágicos", que es un apodo, creo que es un poco tonto, creo que "hook" es un poco más apto. De todos modos, estoy divagando ...

El objetivo de estos es proporcionar casos de ejecución para cuando se accede a los miembros de la información (propiedades o métodos) que no están definidos en el objeto, que pueden usarse para todo tipo de pensamientos "inteligentes" como ocultación de variables, reenvío de mensajes, etc.

Sin embargo, hay un costo: una llamada que invoca estos es alrededor de 10 veces más lenta que una llamada a los miembros definidos.


Esta página probablemente sea útil. (Tenga en cuenta que lo que dice es incorrecto - __set() toma como parámetro tanto el nombre de la variable como el valor. __get() simplemente toma el nombre de la variable).

__get() y __set() son útiles en las funciones de la biblioteca en las que desea proporcionar acceso genérico a las variables. Por ejemplo, en una clase ActiveRecord, es posible que desee que las personas puedan acceder a los campos de la base de datos como propiedades del objeto. Por ejemplo, en el marco PHP de Kohana, puede usar:

$user = ORM::factory(''user'', 1); $email = $user->email_address;

Esto se logra usando __get() y __set() .

Algo similar se puede lograr al usar __call() , es decir, puede detectar cuando alguien llama a getProperty () y setProperty () y maneja en consecuencia.


Los métodos de sobrecarga son especialmente útiles cuando se trabaja con objetos PHP que contienen datos que deben ser fácilmente accesibles. __get () se invoca al acceder a una propiedad inexistente, se llama a __set () cuando se intenta escribir una propiedad inexistente y se invoca __call () cuando se invoca un método inexistente.

Por ejemplo, imagine tener una clase administrando su configuración:

class Config { protected $_data = array(); public function __set($key, $val) { $this->_data[$key] = $val; } public function __get($key) { return $this->_data[$key]; } ...etc }

Esto hace que sea mucho más fácil leer y escribir en el objeto, y le da el cambio para usar una funcionalidad personalizada al leer o escribir en un objeto. Ejemplo:

$config = new Config(); $config->foo = ''bar''; echo $config->foo; // returns ''bar''


La redefinición de __get y __set puede ser especialmente útil en las clases principales. Por ejemplo, si no desea que su configuración se sobrescriba accidentalmente pero aún así desee obtener datos de ella:

class Example { private $config = array(''password'' => ''pAsSwOrD''); public function __get($name) { return $this->config[$name]; } }


Creo que es malo para el diseño tu código. Si conoce y hace un buen diseño, entonces no necesitará usar __set() y __get() dentro de su código. También leer tu código es muy importante y si estás utilizando un estudio (por ejemplo, Zend studio), con __set() y __get() no puedes ver las propiedades de tu clase.


PHP nos permite crear variables de clase dinámicamente que pueden causar problemas. Puedes usar los métodos __set y __get para restringir este comportamiento ... mira el siguiente ejemplo ...

class Person { public $name; public function printProperties(){ print_r(get_object_vars($this)); } } $person = new Person(); $person->name = ''Jay''; //This is valid $person->printProperties(); $person->age = ''26''; //This shouldn''t work...but it does $person->printProperties();

para prevenir arriba puedes hacer esto ..

public function __set($name, $value){ $classVar = get_object_vars($this); if(in_array($name, $classVar)){ $this->$name = $value; } }

Espero que esto ayude...