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.