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
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
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
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
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
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
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
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
¿Has encontrado un error o tienes una sugerencia?
Escribenos