Leccion 29 de 75 12 min de lectura

Constructor y Destructor

El constructor se ejecuta automaticamente al crear un objeto, permitiendo inicializarlo. El destructor se ejecuta cuando el objeto es eliminado de memoria.

El constructor: __construct()

El constructor es un metodo especial que PHP llama automaticamente al usar new. Su nombre siempre es __construct:

PHP
<?php
declare(strict_types=1);

class Usuario
{
    public string $nombre;
    public string $email;

    public function __construct(string $nombre, string $email)
    {
        $this->nombre = $nombre;
        $this->email = $email;
    }
}

// El constructor se llama automaticamente
$usuario = new Usuario('Ana', 'ana@example.com');

echo $usuario->nombre; // Ana
echo $usuario->email;  // ana@example.com

Antes teniamos que asignar propiedades despues de crear el objeto. Con el constructor, lo hacemos todo en un paso.

Parametros opcionales

PHP
<?php
declare(strict_types=1);

class Producto
{
    public string $nombre;
    public float $precio;
    public int $stock;

    public function __construct(string $nombre, float $precio, int $stock = 0)
    {
        $this->nombre = $nombre;
        $this->precio = $precio;
        $this->stock = $stock;
    }
}

$laptop = new Producto('Laptop', 999.99, 10);
$mouse = new Producto('Mouse', 29.99);  // stock = 0

echo $mouse->stock; // 0

Validacion en el constructor

El constructor es ideal para validar datos:

PHP
<?php
declare(strict_types=1);

class CuentaBancaria
{
    public string $titular;
    public float $saldo;

    public function __construct(string $titular, float $saldoInicial = 0)
    {
        if (strlen($titular) < 3) {
            throw new InvalidArgumentException('Titular muy corto');
        }
        if ($saldoInicial < 0) {
            throw new InvalidArgumentException('Saldo no puede ser negativo');
        }

        $this->titular = $titular;
        $this->saldo = $saldoInicial;
    }
}

$cuenta = new CuentaBancaria('Ana Garcia', 1000); // OK
// new CuentaBancaria('AB', 100); // Error!

El destructor: __destruct()

El destructor se ejecuta cuando un objeto es eliminado de memoria. Es util para liberar recursos:

PHP
<?php
declare(strict_types=1);

class Logger
{
    public string $nombre;
    public array $mensajes = [];

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        echo "Logger iniciado: {$nombre}\n";
    }

    public function log(string $mensaje): void
    {
        $this->mensajes[] = $mensaje;
    }

    public function __destruct()
    {
        echo "Guardando " . count($this->mensajes) . " mensajes...\n";
    }
}

$logger = new Logger('app');
$logger->log('Usuario conectado');
$logger->log('Accion realizada');
// Al terminar el script: "Guardando 2 mensajes..."

Cuando se llama al destructor

PHP
<?php
declare(strict_types=1);

class Ejemplo
{
    public string $nombre;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        echo "Creado: {$nombre}\n";
    }

    public function __destruct()
    {
        echo "Destruido: {$this->nombre}\n";
    }
}

$a = new Ejemplo('A');  // Creado: A
$b = new Ejemplo('B');  // Creado: B

$a = null;  // Destruido: A (inmediatamente)

echo "Fin\n";
// Destruido: B (al terminar el script)

Ejemplo practico: Cronometro

PHP
<?php
declare(strict_types=1);

class Cronometro
{
    public string $nombre;
    public float $inicio;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        $this->inicio = microtime(true);
    }

    public function __destruct()
    {
        $duracion = (microtime(true) - $this->inicio) * 1000;
        echo "[{$this->nombre}] {$duracion:.2f}ms\n";
    }
}

function procesarDatos(): void
{
    $crono = new Cronometro('procesarDatos');
    usleep(50000); // 50ms
} // Se destruye al salir

procesarDatos(); // [procesarDatos] 50.23ms

Ejercicios

Ejercicio 1: Clase Libro

Crea una clase Libro con constructor que reciba titulo, autor y anio. El anio debe ser mayor a 1450. Lanza excepcion si no lo es.

Ver solucion
PHP
<?php
declare(strict_types=1);

class Libro
{
    public string $titulo;
    public string $autor;
    public int $anio;

    public function __construct(string $titulo, string $autor, int $anio)
    {
        if ($anio <= 1450) {
            throw new InvalidArgumentException(
                'El anio debe ser mayor a 1450 (invento de la imprenta)'
            );
        }

        $this->titulo = $titulo;
        $this->autor = $autor;
        $this->anio = $anio;
    }
}

$libro = new Libro('Don Quijote', 'Cervantes', 1605);
echo "{$libro->titulo} ({$libro->anio})"; // Don Quijote (1605)

// Esto lanzaria excepcion:
// $antiguo = new Libro('Manuscrito', 'Anonimo', 1200);

Ejercicio 2: Clase Pedido

Crea una clase Pedido que genere un numero unico en el constructor (usa uniqid()) y guarde la fecha. Anade un metodo resumen().

Ver solucion
PHP
<?php
declare(strict_types=1);

class Pedido
{
    public string $numero;
    public string $fecha;
    public string $cliente;
    public float $total;

    public function __construct(string $cliente, float $total)
    {
        $this->numero = uniqid('PED-');
        $this->fecha = date('Y-m-d H:i:s');
        $this->cliente = $cliente;
        $this->total = $total;
    }

    public function resumen(): string
    {
        return "Pedido {$this->numero}\n" .
               "Cliente: {$this->cliente}\n" .
               "Fecha: {$this->fecha}\n" .
               "Total: \${$this->total}";
    }
}

$pedido = new Pedido('Ana Garcia', 150.50);
echo $pedido->resumen();
// Pedido PED-6593a1b2c3d4e
// Cliente: Ana Garcia
// Fecha: 2025-01-15 10:30:45
// Total: $150.50

Ejercicio 3: Clase ConexionSimulada

Crea una clase que muestre "Conexion abierta" en el constructor y "Conexion cerrada" en el destructor. Observa cuando se muestra cada mensaje.

Ver solucion
PHP
<?php
declare(strict_types=1);

class ConexionSimulada
{
    public string $nombre;

    public function __construct(string $nombre)
    {
        $this->nombre = $nombre;
        echo "Conexion abierta: {$nombre}\n";
    }

    public function consultar(string $query): void
    {
        echo "Ejecutando: {$query}\n";
    }

    public function __destruct()
    {
        echo "Conexion cerrada: {$this->nombre}\n";
    }
}

echo "Inicio del programa\n";

$db = new ConexionSimulada('MySQL');
$db->consultar('SELECT * FROM usuarios');

echo "Fin del programa\n";

// Salida:
// Inicio del programa
// Conexion abierta: MySQL
// Ejecutando: SELECT * FROM usuarios
// Fin del programa
// Conexion cerrada: MySQL

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium