Learn how to use enums in Laravel to simplify your code, improve validation, and manage fixed values efficiently. This complete guide covers practical examples, best practices, and tips to boost your Laravel development.
Introduction to Enums in Laravel
In many Laravel apps, we often use strings like 'pending'
or 'approved'
to represent statuses. The problem? It’s easy to mistype and hard to manage.
Enums solve this by letting you define a fixed set of values in a clean, readable way. With PHP 8.1+, enums are built-in, you can use them directly in forms, tables, route and validation — making your code safer and smarter.
Creating Enums in Laravel
Creating an enum in laravel is super easy. For example:
enum OrderStatus: string {
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
}
Now instead of using string everywhere, you use OrderStatus::Pending, which avoids mistake and also improves readability. The above enum and database type enum are completely different.
You may also have seen the real world projects where the roles are based on enum.
enum UserRole: string{
case User = "user"; // or int like 0
case Admin = "admin"; // or int like 1
case SuperAdmin = "super_admin"; // or int like 2
}
Enum Casting
Laravel makes it easy to cast model attributes to enums. This means your database values automatically convert to enum instances when you access them, and back to strings (or integers) when saving.
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $casts = [
'status' => OrderStatus::class, // cast 'status' column to enum
];
}
Now, we can use them directly:
$order = Order::find(1);
if ($order->status === OrderStatus::Pending) {
$order->status = OrderStatus::Approved;
$order->save();
}
The label()
Method in Enums
Sometimes, enum values are not user-friendly or you need to change their display name in UI. The label() method lets you define a human readable label for each case.
enum OrderStatus: string {
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
public function label(): string
{
return match($this) {
self::Pending => 'Pending Approval',
self::Approved => 'Approved',
self::Rejected => 'Rejected',
};
}
}
//Usage:
$status = OrderStatus::Pending;
echo $status->label(); // Pending Approval
// suppose this is used in Order Model
$order->status->label();
//in blade:
{{$order->status->label()}}
Check out more about enum in php docs.
Validation with Enums in Laravel
Its super simple to validate the enum.
$request->validate([
'status' => ['required', Rule::enum(OrderStatus::values())],
]);
//or only and except.
Rule::enum(OrderStatus::class)
->only([OrderStatus::Pending, OrderStatus::Approved]);
Rule::enum(OrderStatus::class)
->except([OrderStatus::Pending, OrderStatus::Approved]);
Now, above validation will check status upon our OrderStatus enum and only valid enum can be saved.
Implicit Enum Binding
Laravel allows you to automatically convert route parameters into enum instances, called implicit enum binding. This makes your controllers cleaner and ensures only valid enum values are passed.
use Illuminate\Support\Facades\Route;
Route::get('/orders/{status}', function (OrderStatus $status) {
return "Selected status: " . $status->label();
});
Other useful methods
cases():
This method returns all the cases of enum as an array.
OrderStatus::cases();
// Output: [OrderStatus::Pending, OrderStatus::Approved, OrderStatus::Rejected]
from($value)
- Gets the enum instance from a value. Throws an error if invalid.
$status = OrderStatus::from('approved');
echo $status->name; // Approved
tryFrom($value)
- Similar to
from()
, but returnsnull
if the value is invalid instead of throwing an error.
$status = OrderStatus::tryFrom('invalid');
var_dump($status); // null
name()
- Returns the case name as declared in the enum.
$status = OrderStatus::Pending;
echo $status->name; // Pending
Custom methods (like label()
or color()
)
- You can define your own methods in the enum for UI or logic purposes.
public function label(): string { ... }
public function color(): string { ... }
FAQ
Can enums be stored in the database?
Yes! You can store the enum’s value
in a database column and use Laravel casting to automatically convert it to an enum instance.
How do I display user-friendly names for enums?
Define a label()
method inside the enum:
public function label(): string { … }
Why should I use enums instead of strings?
Avoid typos and invalid values, Cleaner and more maintainable code, Works well with forms, tables, validation, and routes
What is enum casting?
Enum casting allows a model attribute to automatically convert to and from an enum:
protected $casts = [‘status’ => OrderStatus::class];
What is implicit enum binding?
Laravel can automatically convert route parameters to enum instances:
Route::get(‘/orders/{status}’, fn(OrderStatus $status) => $status->label());
ALSO READ: