Enums en PHP 8.1: pure enums, backed enums y métodos en enumeraciones

Los enums de PHP 8.1 permiten definir tipos con un número fijo de valores posibles. Antes de PHP 8.1, los desarrolladores simulaban enumeraciones con constantes de clase o strings, lo que ofrecía poca seguridad de tipos. Los enums nativos permiten que el sistema de tipos verifique los valores en tiempo de ejecución.

Pure enums: valores sin backing

<?php
enum Direccion
{
    case Norte;
    case Sur;
    case Este;
    case Oeste;
}

function mover(Direccion $dir): string
{
    return match ($dir) {
        Direccion::Norte => 'Moviendo hacia el norte',
        Direccion::Sur   => 'Moviendo hacia el sur',
        Direccion::Este  => 'Moviendo hacia el este',
        Direccion::Oeste => 'Moviendo hacia el oeste',
    };
}

echo mover(Direccion::Norte); // Moviendo hacia el norte
// mover('Norte'); // TypeError — debe ser Direccion
?>

Backed enums: valores string o int

<?php
enum EstadoPedido: string
{
    case Pendiente   = 'pendiente';
    case EnProceso   = 'en_proceso';
    case Enviado     = 'enviado';
    case Entregado   = 'entregado';
    case Cancelado   = 'cancelado';

    public function etiqueta(): string
    {
        return match ($this) {
            self::Pendiente => 'Pendiente de pago',
            self::EnProceso => 'Preparando pedido',
            self::Enviado   => 'En camino',
            self::Entregado => 'Entregado',
            self::Cancelado => 'Cancelado',
        };
    }

    public function esFinal(): bool
    {
        return in_array($this, [self::Entregado, self::Cancelado]);
    }
}

$estado = EstadoPedido::Enviado;
echo $estado->value;     // enviado
echo $estado->name;      // Enviado
echo $estado->etiqueta(); // En camino
var_dump($estado->esFinal()); // false
?>

from() y tryFrom()

<?php
// from() lanza ValueError si el valor no existe
$estado = EstadoPedido::from('enviado');
echo $estado->name; // Enviado

// tryFrom() devuelve null en lugar de lanzar excepción
$desconocido = EstadoPedido::tryFrom('archivado');
var_dump($desconocido); // NULL

// Ejemplo real: leer desde base de datos
$valorBD = 'en_proceso';
$estadoDb = EstadoPedido::from($valorBD);
echo $estadoDb->etiqueta(); // Preparando pedido
?>

cases(): listar todos los valores

<?php
// Obtener todos los casos del enum
$estados = EstadoPedido::cases();
foreach ($estados as $e) {
    echo $e->name . ' ? ' . $e->value . "n";
}
// Pendiente ? pendiente
// EnProceso ? en_proceso
// Enviado ? enviado
// Entregado ? entregado
// Cancelado ? cancelado
?>

Enums con interfaces

<?php
interface TieneColor
{
    public function color(): string;
}

enum RolUsuario: string implements TieneColor
{
    case Admin     = 'admin';
    case Editor    = 'editor';
    case Lector    = 'lector';

    public function color(): string
    {
        return match ($this) {
            self::Admin  => '#e74c3c',
            self::Editor => '#3498db',
            self::Lector => '#2ecc71',
        };
    }

    public function permisosEscritura(): bool
    {
        return $this !== self::Lector;
    }
}

$rol = RolUsuario::Editor;
echo $rol->color();               // #3498db
var_dump($rol->permisosEscritura()); // true
?>

Backed enum con int: tipos de notificación

<?php
enum TipoNotificacion: int
{
    case Email = 1;
    case SMS   = 2;
    case Push  = 4;

    // Combinación de notificaciones con bitmask
    public static function todas(): array
    {
        return self::cases();
    }
}

$tipo = TipoNotificacion::from(2);
echo $tipo->name; // SMS
echo $tipo->value; // 2
?>

La documentación oficial de enumeraciones en PHP cubre las reglas de constantes en enums, la serialización, las restricciones sobre propiedades y los casos de uso con match.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP