Desarrollo

Construcción y destrucción de objetos en PHP

Desarrollo PHP

En el anterior artículo definimos y comenzamos a utilizar los objetos en una densa y extensa explicación sobre los conceptos más básicos pero que deberemos saber para utilizar objetos en PHP. En el actual artículo veremos cómo realizar la construcción de objetos y, en menor medida, la destrucción. Va a ser un artículo más sencillo, corto y, si comprendiste correctamente todo lo aprendido en el artículo anterior, este artículo no te supondrá esfuerzos.

Realmente, en el anterior artículo ya vimos cómo construir un objeto mediante el uso de new. Con ello estábamos realmente lanzando una construcción implícita del objeto con todos sus campos vacíos. De igual forma, la destrucción de objetos será algo a lo que, normalmente, no prestaremos atención, pues PHP lo destruirá por su cuenta al finalizar.

La función predeterminada __construct()

Para crear una clase antes debe construirse. La construcción de objetos se realiza mediante la función __construct(), una función ya predeterminada dentro de la definición de un objeto y que sí, lleva esos dos símbolos de subrayado antes y que son necesarios. Implícitamente, cuando utilizamos new a la hora de crear un objeto, realmente se está llamando al constructor de la clase sin ningún argumento, pero podríamos tener un constructor que aceptara argumentos para inicializar valores.

Una clase sin constructor

Por ejemplo, tenemos la siguiente clase que define de forma sencilla a un producto:

<?php
class Producto {
	private $nombre;
	private $precioBase;
	private $iva;
	private $precioFinal;
}

$producto = new Producto();
?>

Tenemos un objeto llamado Producto que tiene cuatro atributos: su nombre, su precio base, el porcentaje de impuestos que hay que aplicarle y el precio final ya con impuestos. Si creamos un producto como vemos después de la definición de la clase, estará vacío. Vamos a realizar un var_dump de $producto para ver qué nos muestra:

object(Producto)#1 (4) {
  ["nombre":"Producto":private]=>
  NULL
  ["precioBase":"Producto":private]=>
  NULL
  ["iva":"Producto":private]=>
  NULL
  ["precioFinal":"Producto":private]=>
  NULL
}

Como vemos, tenemos un objeto Producto con todos sus atributos a null. Por tanto, deberíamos ahora utilizar funciones (que no hemos creado en este ejemplo) para introducir los valores de esos atributos. Obviamente, esas funciones se pueden crear (es lo normal), pero también podemos hacerlo todo en un paso con el constructor. Vamos a definirlo entonces.

Definiendo el constructor

<?php
class Producto {

	private $nombre;
	private $precioBase;
	private $iva;
	private $precioFinal;
	
	function __construct($nombre, $precioBase, $iva = 21.0) {
		$this->nombre = $nombre;
		$this->precioBase = $precioBase;
		$this->iva = $iva;
		$this->precioFinal = $precioBase + $precioBase * $iva / 100;
	}
}

$producto = new Producto('Teléfono móvil', 300);
?>

Hemos definido nuestro primer constructor, siendo éste muy sencillo. Hemos decidido que sólo tenga tres de los cuatro atributos definidos, pues el precio final lo debemos obtener desde el precio base y los impuestos (no tendría sentido aquí que pudiéramos modificar el precio final sin tener en cuenta los otros valores, y eso no es programación, es la lógica del programa).

Como veis, ahora nuestro new Producto necesita de esos argumentos para que el objeto sea creado. Si no se los indicáramos, se produciría un error, pues ahora el constructor de la clase es el que hemos definido nosotros y no el que viene por defecto sin argumentos. Si quisiéramos que el básico siguiera funcionando, deberíamos poner todos los argumentos con un valor null por defecto y, así, podríamos utilizarlo con o sin argumentos.

Dentro del constructor es un espacio más de programación

El constructor no es sólo para definir las variables que nos han pasado. Podemos colocar lógica de programación, pues actúa como una función más. En este caso, como vemos, se calcula directamente dentro del constructor el precio final a través del precio base y del IVA indicado. Y, como hemos puesto el IVA con un valor por defecto en el argumento, podemos obviarlo en el constructor.

Si hiciéramos un var_dump ahora, tendríamos lo siguiente:

object(Producto)#1 (4) {
  ["nombre":"Producto":private]=>
  string(16) "Teléfono móvil"
  ["precioBase":"Producto":private]=>
  int(300)
  ["iva":"Producto":private]=>
  float(21)
  ["precioFinal":"Producto":private]=>
  float(363)
}

Ahora tenemos nuestro objeto construido y listo para ser usado. El nombre y el precio base han cogido los valores que hemos indicado, mientras que, al no haber indicado el IVA, ha cogido el valor por defecto de 21,0. Por último, dentro del constructor se calculaba el precio final y, como vemos, es el precio que ha guardado. La construcción de objetos no es un tema excesivamente complejo.

El destructor

Si la construcción de objetos ha sido sencilla, la destrucción lo será más. Sinceramente, creo que yo nunca he utilizado el destructor de una clase jamás. La destrucción de la clase se realiza automáticamente en la finalización del script de PHP, por lo que no es algo que se suele tener en cuenta. La destrucción automática libera las variables utilizadas de la memoria y, por ello, en PHP no nos solemos preocupar de ello.

Sin embargo, puede que haya ocasiones donde sea interesante conocer que existe la función para destruir una clase, y esta es __destruct(). ¿Para qué puede servirnos? Pues, por ejemplo, para mostrar algún mensaje por pantalla o para ejecutar algún código que sólo queremos que se ejecute al finalizar el script. Veamos un ejemplo sencillo:

<?php
class Producto {

	private $nombre;
	private $precioBase;
	private $iva;
	private $precioFinal;
	
	function __construct($nombre, $precioBase, $iva = 21.0) {
		$this->nombre = $nombre;
		$this->precioBase = $precioBase;
		$this->iva = $iva;
		$this->precioFinal = $precioBase + $precioBase * $iva / 100;
	}
	function __destruct() {
		echo 'Destrucción';
	}
}

$producto = new Producto('Teléfono móvil', 300);

echo '<pre>';
var_dump($producto);
echo '</pre>';
?>

Si ejecutamos este código, nos encontraremos por pantalla lo siguiente:

object(Producto)#1 (4) {
  ["nombre":"Producto":private]=>
  string(16) "Teléfono móvil"
  ["precioBase":"Producto":private]=>
  int(300)
  ["iva":"Producto":private]=>
  float(21)
  ["precioFinal":"Producto":private]=>
  float(363)
}

Destrucción

Vemos la clase creada correctamente, como hemos visto cuando hemos hablado del destructor y también vemos que, al final del script, se ha destruido la clase. Lo sabemos gracias a ese mensaje que hemos puesto en el método __destruct() que imprimía por pantalla el texto “Destrucción”.

Resumen

En PHP podríamos vivir sin constructores ni destructores, aunque en otros lenguajes de programación su definición, especialmente la del constructor de objetos, es totalmente obligatoria. Pero aquí se nos facilita mucho todo y podemos vivir sin ellos, como vimos en el artículo anterior, aunque nos pueden ser útiles para definir los primeros valores de los atributos. Quizá la mayor utilidad que obtendremos del constructor sea cuando veamos herencia entre clases, pero eso ya llegará.

Este artículo ha sido corto y sencillo, para coger un poco de aire y afianzar los conocimientos básicos de la programación orientada a objetos. En el próximo artículo veremos algunos detalles más, también sin necesidad de que sean densos, antes de nuestra primera práctica con objetos.

Deja una respuesta