ENUMS EN PHP: CÓMO FUNCIONAN Y EJEMPLOS
Una de las novedades de versión 8.1 de php es que se añade el tipo enums (enumerados) que son un tipo de datos definido por el usuario y que consiste en un conjunto de valores posibles. De igual manera que los enum en mysql. Los enums se construyen sobre clases y objetos. Se comportan de forma similar y tienen casi los mismos requisitos. Los enums comparten los mismos espacios de nombres que las clases, las interfaces y los traits.Ejemplo declaración de enums en php:
enum tipoVehiculos
{
case Coche;
case Camion;
case Moto;
case Furgoneta;
}
//Para mostrar uno de los enums:
$vehiculo = tipoVehiculos::Coche;
var_dump(tipoVehiculos->name);
//Mostrará "Coche"
enum tipoVehiculos2: string
{
case Coche = 'Coche';
case Camion = 'Camion';
case Moto = 'Moto';
case Furgoneta = 'Furgo';
}
//Para mostrar uno de los enums:
$vehiculo = tipoVehiculos2::Furgoneta;
var_dump(tipoVehiculos->value);
//Mostrará "Furgo"
Os invito a ver los enums en mysql.
Tipos de ENUMS
// 1. Enum básico (solo nombres)
enum Status
{
case Pending;
case Approved;
case Rejected;
}
// 2. Enum Backed (el más usado - con valor)
enum OrderStatus: string
{
case Pending = 'pending';
case Paid = 'paid';
case Shipped = 'shipped';
case Delivered = 'delivered';
case Cancelled = 'cancelled';
}
// 3. Enum con valor entero
enum Role: int
{
case User = 1;
case Admin = 2;
case Super = 3;
}
//USO
$status = OrderStatus::Pending;
// Comparaciones seguras
if ($order->status === OrderStatus::Paid) { ... }
// Con base de datos (el backed value)
$order->status = OrderStatus::Shipped->value; // 'shipped'
Métodos y lógica dentro del ENUM
enum GameStatus: string
{
case Pending = 'pending';
case Joining = 'joining';
case InProgress = 'in_progress';
case Completed = 'completed';
case Cancelled = 'cancelled';
//Método para saber si se puede cambiar de estado
public function canTransitionTo(self $to): bool
{
return match ($this) {
self::Pending => in_array($to, [self::Joining, self::Cancelled]),
self::Joining => $to === self::InProgress,
self::InProgress => in_array($to, [self::Completed, self::Cancelled]),
self::Completed,
self::Cancelled => false, // estados finales
};
}
// Método extra
public function isFinal(): bool
{
return in_array($this, [self::Completed, self::Cancelled]);
}
}
//USO
$current = GameStatus::from($game->status);
if ($current->canTransitionTo(GameStatus::Completed)) {
$game->update(['status' => GameStatus::Completed->value]);
}
Funciones útiles
- "OrderStatus::cases()" → devuelve todos los casos.
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; case Shipped = 'shipped'; case Delivered = 'delivered'; case Cancelled = 'cancelled'; } $all = OrderStatus::cases(); var_dump($all); //Salida array(5) { [0] => enum(OrderStatus::Pending) [1] => enum(OrderStatus::Paid) [2] => enum(OrderStatus::Shipped) [3] => enum(OrderStatus::Delivered) [4] => enum(OrderStatus::Cancelled) - "OrderStatus::from('paid')" → convierte string a Enum.
Busca el valor (->value) y devuelve el caso correspondiente. Si el valor no existe, lanza una excepción ValueError. Ideal cuando si se está 100% seguro de que el valor es correcto.
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; case Shipped = 'shipped'; case Delivered = 'delivered'; case Cancelled = 'cancelled'; } $status1 = OrderStatus::from('paid'); // Funciona $status2 = OrderStatus::from('shipped'); // Funciona var_dump($status1); var_dump($status2); //Salida enum(OrderStatus::Paid) enum(OrderStatus::Shipped) // Esto lanza error: $status3 = OrderStatus::from('invalid'); // ValueError pq no existe. - "OrderStatus::tryFrom('invalid')" → null si no existe (sin excepción). Convierte string a Enum (seguro, sin error).
Es la versión segura de from(). Si el valor existe → devuelve el Enum. Si no existe → devuelve null. Recomendado cuando el dato viene de usuario, API externa, formularios, etc.
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; case Shipped = 'shipped'; case Delivered = 'delivered'; case Cancelled = 'cancelled'; } $status1 = OrderStatus::tryFrom('paid'); // OrderStatus::Paid $status2 = OrderStatus::tryFrom('invalid'); // null (no lanza error) pq no existe. $status3 = OrderStatus::tryFrom('shipped'); // OrderStatus::Shipped var_dump($status1); var_dump($status2); var_dump($status3); //Salida enum(OrderStatus::Paid) enum(null) enum(OrderStatus::Shipped) //Ejemplo práctico: $status = OrderStatus::tryFrom($request->input('status')); if ($status === null) { abort(400, 'Estado inválido'); } - "->value" y "->name"
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; case Shipped = 'shipped'; case Delivered = 'delivered'; case Cancelled = 'cancelled'; } $status = OrderStatus::Paid; echo $status->value; // El valor real (string/int) -> 'paid'. echo $status->name; // El nombre del caso ->'Paid'