Métodos mágicos
Son funciones definidas por PHP, las cuales el programador se encarga de definir la implementación. Sin embargo, el llamado de estas funciones ocurre cuando sea necesario y no puede ser llamadas directamente. Todas inician con una doble barra horizontal (__
).
Los métodos mágicos conocidos anteriormente son:
- Constructor de un objeto:
__construct()
- Destructor de un objeto:
__destruct()
- Comportamiento de string de un objeto:
__toString()
Modificación y lectura de atributos
Para acceder y modificar atributos de un objeto se puede utilizar las funciones getter y setter, comunes en lenguajes como JAVA o C++. También es posible utilizar los métodos mágicos __get()
y __set()
<?php class Alumno { private $cuenta; private $nombre; private $carrera; public function __get($atributo) { return $this->$atributo; } public function __set($atributo, $valor) { $this->$atributo = $valor; } } // Implementación del objeto $alumno1 = new Alumno(); // No está accediendo a los atributos, los cuales son private. // Se está accediendo mediante los métodos mágicos. $alumno1->cuenta = '20151000001'; $alumno1->nombre = 'Ruben Gomez'; $alumno1->carrera = 'Ingenieria en Sistemas'; echo 'Un alumno se ha creado', PHP_EOL; echo 'Cuenta: ', $alumno1->cuenta, PHP_EOL; echo 'Nombre: ', $alumno1->nombre, PHP_EOL; echo 'Carrera: ', $alumno1->carrera, PHP_EOL; ?>
Inyección de atributos
Uno de los efectos secundarios de utilizar estos métodos, sin una validación correspondiente, es que podemos inyectar atributos a un objeto en tiempo de ejecución, modificando la estructura inicial de dicho objeto.
<?php $alumno2 = new Alumno(); $alumno2->nombre = 'Juan Pueblo'; $alumno2->cuenta = '20121001234'; $alumno2->carrera = 'Medicina'; // Inyección de atributo al objeto. $alumno2->centro = 'Ciudad Universitaria'; var_dump($alumno2); /* object(Alumno)#1 (4) { ["cuenta":"Alumno":private]=> string(11) "20121001234" ["nombre":"Alumno":private]=> string(11) "Juan Pueblo" ["carrera":"Alumno":private]=> string(8) "Medicina" ["centro"]=> string(20) "Ciudad Universitaria" } */ ?>
Para evitar la inyección de atributos se puede utilizar la función de PHP property_exists()
, la cual revisa si un atributo existe o no dentro de un objeto.
<?php class Alumno { private $cuenta; private $nombre; private $carrera; public function __get($atributo) { if (property_exists($this, $atributo)) return $this->$atributo; } public function __set($atributo, $valor) { if (property_exists($this, $atributo)) $this->$atributo = $valor; } } // Probar nuevamente la inyección de atributos $alumno3 = new Alumno(); $alumno3->nombre = 'Juan Pueblo'; $alumno3->cuenta = '20121001234'; $alumno3->carrera = 'Medicina'; $alumno3->centro = 'Ciudad Universitaria'; var_dump($alumno3); /* object(Alumno)#1 (4) { ["cuenta":"Alumno":private]=> string(11) "20121001234" ["nombre":"Alumno":private]=> string(11) "Juan Pueblo" ["carrera":"Alumno":private]=> string(8) "Medicina" } */ ?>
Ventajas y desventajas
- La mayor ventaja que poseen estas funciones radica en el reducido código que se genera, ya que por cada atributo existente podría crear dos funciones.
- Una desventaja de estos métodos consiste en la dificultad que conlleva a los IDE’s identificarlos.
- Otra desventaja es que se requiere documentar el uso de dichas funciones para orientar a otros programadores de su uso.
- Las funciones tradicionales suelen más rápidas que las funciones mágicas y esto se entiende, ya que las segundas necesitan una revisión de los posibles atributos de un objeto.