Leccion 41 de 75 10 min de lectura

Enumeraciones (Enums)

PHP 8.1 introduce Enums, una forma de definir un conjunto cerrado de valores posibles con seguridad de tipos. Reemplazan el uso de constantes para representar estados o categorias.

Enums básicos (Unit Enums)

Un enum define un conjunto fijo de valores posibles:

PHP
<?php

declare(strict_types=1);

enum Estado
{
    case Pendiente;
    case Procesando;
    case Completado;
    case Cancelado;
}

function procesarPedido(Estado $estado): string
{
    return match ($estado) {
        Estado::Pendiente => 'Esperando procesamiento',
        Estado::Procesando => 'En proceso...',
        Estado::Completado => 'Listo para envio',
        Estado::Cancelado => 'Pedido cancelado',
    };
}

$estado = Estado::Pendiente;
echo procesarPedido($estado); // Esperando procesamiento

// Type safety: esto genera error
// procesarPedido('pendiente'); // Error!

Backed Enums (con valores)

Los Backed Enums asocian cada caso con un valor escalar (string o int), util para guardar en base de datos:

PHP
<?php

declare(strict_types=1);

// Backed enum con strings
enum Rol: string
{
    case Admin = 'admin';
    case Editor = 'editor';
    case Usuario = 'user';
}

// Obtener el valor
$rol = Rol::Admin;
echo $rol->value; // 'admin'
echo $rol->name;  // 'Admin'

// Crear desde valor (para datos de BD)
$rolDesdeDB = Rol::from('editor');      // Rol::Editor
$rolOpcional = Rol::tryFrom('invalido'); // null (no lanza error)

// Backed enum con integers
enum Prioridad: int
{
    case Baja = 1;
    case Media = 2;
    case Alta = 3;
    case Critica = 4;
}

$prioridad = Prioridad::Alta;
echo $prioridad->value; // 3

Metodos en Enums

Los enums pueden tener metodos, igual que las clases:

PHP
<?php

declare(strict_types=1);

enum Color: string
{
    case Rojo = '#FF0000';
    case Verde = '#00FF00';
    case Azul = '#0000FF';

    public function rgb(): array
    {
        return match ($this) {
            self::Rojo => [255, 0, 0],
            self::Verde => [0, 255, 0],
            self::Azul => [0, 0, 255],
        };
    }

    public function esCalido(): bool
    {
        return $this === self::Rojo;
    }

    // Metodo estatico
    public static function aleatorio(): self
    {
        $casos = self::cases();
        return $casos[array_rand($casos)];
    }
}

$color = Color::Rojo;
echo $color->value;        // #FF0000
print_r($color->rgb());    // [255, 0, 0]
echo $color->esCalido();   // true

$colorRandom = Color::aleatorio();

Listar todos los casos

PHP
<?php

declare(strict_types=1);

enum DiaSemana: int
{
    case Lunes = 1;
    case Martes = 2;
    case Miercoles = 3;
    case Jueves = 4;
    case Viernes = 5;
    case Sabado = 6;
    case Domingo = 7;
}

// Obtener todos los casos
$dias = DiaSemana::cases();
foreach ($dias as $dia) {
    echo "{$dia->name}: {$dia->value}\n";
}

// Util para generar selects en formularios
echo '<select name="dia">';
foreach (DiaSemana::cases() as $dia) {
    echo "<option value=\"{$dia->value}\">{$dia->name}</option>";
}
echo '</select>';

Enums con interfaces

PHP
<?php

declare(strict_types=1);

interface Describible
{
    public function descripcion(): string;
}

enum EstadoPago: string implements Describible
{
    case Pendiente = 'pending';
    case Pagado = 'paid';
    case Fallido = 'failed';
    case Reembolsado = 'refunded';

    public function descripcion(): string
    {
        return match ($this) {
            self::Pendiente => 'Esperando pago del cliente',
            self::Pagado => 'Pago recibido correctamente',
            self::Fallido => 'El pago no pudo procesarse',
            self::Reembolsado => 'Dinero devuelto al cliente',
        };
    }

    public function esExitoso(): bool
    {
        return $this === self::Pagado;
    }
}

$estado = EstadoPago::from('paid');
echo $estado->descripcion(); // Pago recibido correctamente

Ejercicios

Ejercicio 1: Enum Talla

Crea un enum Talla backed con string (XS, S, M, L, XL) y un metodo siguiente() que retorne la talla mayor.

Ver solucion
PHP
<?php

declare(strict_types=1);

enum Talla: string
{
    case XS = 'xs';
    case S = 's';
    case M = 'm';
    case L = 'l';
    case XL = 'xl';

    public function siguiente(): ?Talla
    {
        return match ($this) {
            self::XS => self::S,
            self::S => self::M,
            self::M => self::L,
            self::L => self::XL,
            self::XL => null,
        };
    }
}

$talla = Talla::M;
echo $talla->siguiente()?->value; // l

Ejercicio 2: Enum HttpStatus

Crea un enum HttpStatus backed con int para codigos HTTP comunes (200, 201, 400, 404, 500) con un metodo esExitoso().

Ver solucion
PHP
<?php

declare(strict_types=1);

enum HttpStatus: int
{
    case Ok = 200;
    case Created = 201;
    case BadRequest = 400;
    case NotFound = 404;
    case ServerError = 500;

    public function esExitoso(): bool
    {
        return $this->value >= 200 && $this->value < 300;
    }

    public function mensaje(): string
    {
        return match ($this) {
            self::Ok => 'OK',
            self::Created => 'Created',
            self::BadRequest => 'Bad Request',
            self::NotFound => 'Not Found',
            self::ServerError => 'Internal Server Error',
        };
    }
}

$status = HttpStatus::NotFound;
echo $status->esExitoso(); // false
echo $status->mensaje();   // Not Found

¿Te está gustando el curso?

Cursos premium con proyectos reales y soporte.

Descubrir cursos premium