Buscar este blog

29 de julio de 2010

PHP Orientado a Objetos for Beginners II

PHP Orientado a Objetos for Beginners II
Continuamos con la segunda parte del artículo PHP Orientado a Objetos for Beginners (publicado hace unos días), pero ahora enfocados en las herramientas que nos ayudarán a desarrollar nuestras aplicaciones web con PHP OOP más fácilmente.

En este artículos vamos a conocer sobre los métodos mágicos y observar como funcionan los constructores y destructores, como podemos convertir un objeto en un string y como usar las herencias. Y todo explicado de una manera sencilla y práctica...

Importante: Si no tienes claro los conceptos de OOP con PHP, dirígete a la Parte 1 de este artículo. Allí comentamos los conceptos generales y hacemos una introducción a la Programación Orientada a Objetos con PHP.

Los métodos mágicos en OOP

Para facilitar el uso de objetos, PHP proporciona una serie de métodos mágicos o métodos especiales que son llamados cuando ciertas acciones comunes ocurren dentro de los objetos. Esto permite a los desarrolladores realizar una variedad de tareas útiles con cierta facilidad.



Importante: Los ejemplos que veremos son la continuación de los ejemplos propuestos en la parte 1, acude a ellos si tienes alguna duda.

Usando Constructores y Destructores

Cuando un objeto es instanciado, muchas veces es conveniente establecer algunas cosas. Por ello, PHP proporciona el método mágico __construct(), que se llamará automáticamente cada vez que un nuevo objeto es creado.

Para ilustrar el concepto de constructores, vamos a añadir un constructor a MyClass que imprimirá un mensaje cuando una nueva instancia de la clase sea creada:
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}
// Crea un nuevo objeto$obj = new MyClass;
// Imprime el valor de $prop1echo $obj->getProperty();
// Imprime un mensaje al final del archivoecho "Fin del archivo.
"
;?>

Toma nota: __CLASS__ retorna el nombre de la clase que fue llamada; esto es conocido como una constante mágica. Hay una amplia gama de constantes mágicas disponibles, puedes leer un poco más de ellas en el manual de PHP.

Ahora recarga el archivo en tu navegador y verás el siguiente resultado:
¡La clase "MyClass" fue iniciada!
¡Soy la propiedad de una clase!
Fin del archivo.

Para llamar a una función cuando el objeto se destruye, podemos hacer uso del método mágico __destruct(). Este es muy útil para la limpieza de una clase (cerrar la conexión a una base de datos, por ejemplo).
Continuando con nuestro ejemplo, imprimiremos un mensaje cuando el objeto es destruido. Para ello, definimos el método __destruct() en MyClass:
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}
// Crea un nuevo objeto$obj = new MyClass;
// Imprime el valor de $prop1echo $obj->getProperty();
// Imprime un mensaje al final del archivoecho "Fin del archivo.
"
;?>

Con el destructor definido, recarga la página de ejemplo y deberá aparecerte el siguiente resultado:
¡La clase "MyClass" fue iniciada!
¡Soy la propiedad de una clase!
Fin del archivo.
¡La clase "MyClass" fue destruida!
PHP libera todos los recursos, cuando llega al final del archivo.
Para entender mejor como funciona el destructor, ahora destruye manualmente el objeto usando la función unset():
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}
// Crea un nuevo objeto$obj = new MyClass;
// Imprime el valor de $prop1echo $obj->getProperty();
// Destruye el objetounset($obj);
// Imprime un mensaje al final del archivoecho "Fin del archivo.
"
;?>

Ahora recarga la página y verás como el resultado ha cambiado:
¡La clase "MyClass" fue iniciada!
¡Soy la propiedad de una clase!
¡La clase "MyClass" fue destruida!
Fin del archivo.

Convirtiendo un Objeto a String

Para evitar que un error aparezca al intentar imprimir la instancia de MyClass como string (ó cadena de texto), otro método mágico es útil: __toString().
Si no utilizamos __toString(), tratar de imprimir un objeto como cadena nos devolverá un error fatal. Para demostrarlo, intenta imprimir el objeto con un echo, sin utilizar el método mágico:
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}
// Crea un nuevo objeto$obj = new MyClass;
// Imprime el objeto como un stringecho $obj;
// Destruye el objetounset($obj);
// Imprime un mensaje al final del archivoecho "Fin del archivo.
"
;?>

Esto resulta en lo siguiente:
¡La clase "MyClass" fue iniciada!

Catchable fatal error: Object of class MyClass could not be converted to string in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 40
Para evitar este error, vamos a añadir el método __toString():
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function __toString()
    {
        echo
"Usando el método toString: ";
        return
$this->getProperty();
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}
// Crea un nuevo objeto$obj = new MyClass;
// Imprime el objeto como un stringecho $obj;
// Destruye el objetounset($obj);
// Imprime un mensaje al final del archivoecho "Fin del archivo.
"
;?>

En este caso, el intentar convertir el objeto en un string nos devuelve una llamada al método getProperty(). Carga el script en un archivo y pruébalo en el navegador. Verás que aparece lo siguiente:
¡La clase "MyClass" fue iniciada!
Usando el método toString: ¡Soy la propiedad de una clase!
¡La clase "MyClass" fue destruida!
Fin del archivo.

Tip: Adicionalmente a los métodos mágicos comentados en este artículo, existen más de ellos. Para una revisión completa de los métodos mágicos, puedes darle una mirada a esta página del manual de PHP.

Usando herencia de clases

Las clases pueden heredar los métodos y propiedades de otras clases usando la palabra extends. Por ejemplo, para crear una segunda clase que extienda MyClass y añada un método, podrías añadir los siguiente a tu archivo de prueba:
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function __toString()
    {
        echo
"Usando el método toString: ";
        return
$this->getProperty();
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}

class
MyOtherClass extends MyClass{
   
public function newMethod()
    {
        echo
"Desde un nuevo método en " . __CLASS__ . ".
"
;
    }
}
// Crea un nuevo objeto$newobj = new MyOtherClass;
// Imprime el objeto como un stringecho $newobj->newMethod();
// Usa el método de la clase padreecho $newobj->getProperty();?>

Ahora, recarga el archivo en el navegador y te aparecerá lo que sigue:
¡La clase "MyClass" fue iniciada!
Desde un nuevo método en "MyOtherClass".
¡Soy la propiedad de una clase!
¡La clase "MyClass" fue destruida!

Sobrescribiendo las propiedades y métodos heredados

Para cambiar el comportamiento de una propiedad o método en una nueva clase, simplemente podrías sobrescribirlos, declarándolos otra vez en la nueva clase:
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function __toString()
    {
        echo
"Usando el método toString: ";
        return
$this->getProperty();
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}

class
MyOtherClass extends MyClass{
   
public function __construct()
    {
        echo
"Un nuevo constructor en " . __CLASS__ . ".
"
;
    }

   
public function newMethod()
    {
        echo
"Desde un nuevo método en " . __CLASS__ . ".
"
;
    }
}
// Crea un nuevo objeto$newobj = new MyOtherClass;
// Imprime el objeto como un stringecho $newobj->newMethod();
// Usa el método de la clase padreecho $newobj->getProperty();?>

Esto cambiará la salida en el navegador a:
Un nuevo constructor en MyOtherClass.
Desde un nuevo método en MyOtherClass.
¡Soy la propiedad de una clase!
¡La clase "MyClass" fue destruida!

Preservando la funcionalidad del método original cuando sobrescribimos métodos heredados

Para añadir una nueva funcionalidad a un método heredado, pero queremos mantener intacto a este, vamos a usar la palabra parent con el operador de resolución de ámbito (::):
class MyClass{
   
public $prop1 = "¡Soy la propiedad de una clase!";

   
public function __construct()
    {
        echo
'¡La clase "', __CLASS__, '" fue iniciada!
'
;
    }

   
public function __destruct()
    {
        echo
'¡La clase "', __CLASS__, '" fue destruida!
'
;
    }

   
public function __toString()
    {
        echo
"Usando el método toString: ";
        return
$this->getProperty();
    }

   
public function setProperty($newval)
    {
       
$this->prop1 = $newval;
    }

   
public function getProperty()
    {
        return
$this->prop1 . "
"
;
    }
}

class
MyOtherClass extends MyClass{
   
public function __construct()
    {
       
parent::__construct(); // LLama al constructor de la clase padre
       
echo "Un nuevo constructor en " . __CLASS__ . ".
"
;
    }

   
public function newMethod()
    {
        echo
"Desde un nuevo método en " . __CLASS__ . ".
"
;
    }
}
// Crea un nuevo objeto$newobj = new MyOtherClass;
// Imprime el objeto como un stringecho $newobj->newMethod();
// Usa el método de la clase padreecho $newobj->getProperty();?>

Esto muestra el resultado de ambos: Del constructor de la clase padre y del constructor de la nueva clase:
¡La clase "MyClass" fue iniciada!
Un nuevo constructor en MyOtherClass.
Desde un nuevo método en MyOtherClass.
¡Soy la propiedad de una clase!
¡La clase "MyClass" fue destruida!

En este artículo hemos visto, rápida y claramente, cómo funcionan los métodos mágicos en OOP y lo práctico que pueden sernos, cómo usar los constructores y destructores y un método que nos será muy útil para imprimir nuestros objetos. También hemos comprendido el concepto de herencias y de que maneras podemos aplicarla. Aún quedan temas introductorios a la POO con PHP por comentar, pero los dejamos pendientes para un próximo post.

Fuente: Este tutorial es un extracto del libro Pro PHP and jQuery, en inglés: Object-Oriented PHP for Beginners.

Via baluart.net
 

No hay comentarios:

Publicar un comentario