martes, 16 de febrero de 2010

Los métodos mágicos en PHP

Los métodos mágicos son una importante característica de PHP, que permite cambiar la funcionalidad interna de las clases a través de la implementación de ciertos métodos. En este artículo voy a comentar para que sirve cada uno de ellos.

Que y cuales son los métodos mágicos

Los métodos mágicos, son métodos que son llamados automáticamente por PHP ante determinadas situaciones. Se caracterizan porque su nombre empieza por “__” (dos guiones bajos). Estos son:

  • __construct()
  • __destruct()
  • __call()
  • __get()
  • __set()
  • __isset()
  • __unset()
  • __sleep()
  • __wakeup()
  • __toString()
  • __clone()
Cada uno de estos métodos es llamado por PHP cuando cierto “evento” ocurre (este evento depende de cual método estemos hablando). Al implementar un método de estos, nos aseguramos de que cierto código se ejecute cuando el evento en cuestión ocurra.
Para los que conocen Java. Sería como sobreescribir algunos métodos de la clase Object, de manera que cambiemos la funcionalidad interna del objeto (como cuando sobreescribimos finalize() o toString()).
Por ejemplo, el método __destruct() es llamado cuando un objeto es destruido. Al implementarlo, nos aseguramos de que PHP, al destruir un objeto ejecute cierto código (obviamente este “cierto código” es la implementación que le demos al método).

Para que sirven los métodos mágicos

Todos son muy diferentes, y sirven para cosas distintas, por lo tanto la mejor manera de entender para que sirven es ver en detalle cada uno de ellos.


  • __construct()

    Este método apareció a partir de PHP 5. Es un constructor, se usa en reemplazo del constructor de PHP 4. Es llamado cuando se construye un objeto, y es conveniente usarlo, ya que el viejo constructor (el método con el mismo nombre de la clase) es deprecated.


  • __destruct()

    Este método también apareció a partir de PHP 5, y es llamado obviamente cuando un objeto es destruido. El método no toma parámetros ni retorna nada, se utiliza generalmente para liberar recursos.


  • __call()

    Este método es llamado cuando un método no es encontrado. Sirve para encontrar métodos no definidos evitando que se produzca un error. Aunque a simple vista tal vez no vean a este método como muy útil… ¡SI LO ES! Como ya sabrán, PHP no soporta la sobrecarga de métodos, pero con este método mágico, se puede “simular” el overloading. Se pueden hacer muchas cosas interesantes con este método, miren este ejemplo:
    < ?php
    class Person {
    private $firstName;
    private $lastName;
    private $age;
    private $country;
    function __call($method, $arguments) {
    $prefix = strtolower(substr($method, 0, 3));
    $property = strtolower(substr($method, 3));
    if (empty($prefix) || empty($property)) {
    return;
    }
    if ($prefix == "get" && isset($this->$property)) {
    return $this->$property;
    }
    if ($prefix == “set”) {
    $this->$property = $arguments[0];
    }
    }
    }
    $personObj = new Person;
    $personObj->setFirstName(“Pepe”);
    $personObj->setLastName(“Argento”);
    $personObj->setAge(50);
    $personObj->setCountry(“Argentina”);
    echo “Nombre: “.$personObj->getFirstName().” “.$personObj->getLastName().”n”;
    echo “Edad: “.$personObj->getAge().”n”;
    echo “País: “.$personObj->getCountry().”n”;
    ?>
    ¿Ahora si les parece interesante este método verdad? acabamos de ahorrarnos la tediosa tarea de tener que crear los métodos setX() y getX() para cada método.


  • __get() y __set()

    Estos dos métodos también son muy muy útiles. Son llamados cuando un atributo no existe. Y pueden utilizarse para muchas cosas interesantes. Por ejemplo, cuando necesitamos tener una manera de acceder a atributos que no conocemos en tiempo de compilación, o si queremos crear atributos haciéndolos formar parte de un array pero que se utilicen como si fueran atributos normales. Miren por ejemplo esto:
    < ?
    class Test {
    var $properties;
    function __set($property_name, $val) {
    $this->properties[$property_name] = $val;
    }
    function __get($property_name) {
    if(isset($this->properties[$property_name])) {
    return($this->properties[$property_name]);
    } else {
    return(NULL);
    }
    }
    }
    $testObj = new Test();
    $testObj->anyProperty = “Any property”;
    echo $testObj->anyProperty;
    ?>


  • __isset()

    Es llamado cuando se le pasa un atributo NO definido al método isset(). Puede aplicarse igual que __set() y __get(), pero para utilizar el método isset() sobre el atributo. Este método está a partir de PHP 5.


  • __unset()

    Igual que __isset() pero para utilizar con el método unset(). También está a partir de PHP 5.


  • __sleep()

    Es llamado al serializar un objeto por serialize(). Puede utilizarse para limpiar variables que no desean ser serializadas, etc.


  • __wakeup()

    Es llamado al deserializar un objeto por unserialize(). Es utilizado generalmente para realizar algunas tareas de “reinicialización”.


  • __toString()

    Es llamado cuando se trata a un objeto como una cadena. Vendría a ser lo mismo que el método toString de la clase Object de Java. Un ejemplo de como implementarlo:
    < ?php
    class Person {
    var $name;
    function __toString() {
    return $this->name;
    }
    }
    $personObj = new Person();
    $personObj->name = “Pepe Argento”;
    echo $personObj;
    ?>


  • __clone()

    Este método apareció a partir de PHP 5. Es llamado cuando un objeto es clonado. Para los que conocen C++, este método sería como un constructor de copia.


  • __autoload()

    Es llamado cuando una clase no es encontrada. Puede utilizarse para intentar importarla en ese momento. Así:
    < ?php
    function __autoload($className) {
    require_once $className . '.php';
    }
    $obj1 = new AnyClass();
    $obj2 = new OtherClass();
    ?>
    

1 comentario:

  1. El mejor tutorial sobre metodos magicos en PHP. Es bien claro y objetivo a la vez. Gracias amigo y espero seguir leyendote. Saludos.

    ResponderEliminar