Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ivqonsanada's avatar

Laravel 11 Enum Casting

How to use laravel 11 enum casting when the value is number but need to cast it to its name version?

enum BookingType: int implements HasLabel
{
    case Booking = 0;
    case NotAvailable = 1;
    case Subscription = 2;
 
    public static function toName($value): string
    {
        return match ($value) {
            self::Booking->value => 'Booking',
            self::NotAvailable->value => 'NotAvailable',
            self::Subscription->value => 'Subscription',
        };
    }

currently i can only make it via get attribute

public function getTypeAttribute($value)
    {
        return BookingType::toName($value);
    }

is there way to make it cleaner like:

   protected function casts(): array
    {
        return [
           'type' => BookingType::class
        ];
    }
0 likes
4 replies
LaryAI's avatar
Level 58

In Laravel 11, you can use custom casting to achieve the desired behavior of casting an enum value to its name. You can create a custom cast class that handles the conversion. Here’s how you can do it:

  1. Create a Custom Cast Class:

First, create a custom cast class that will handle the conversion of the enum value to its name.

php artisan make:cast BookingTypeCast

Then, implement the CastsAttributes interface in the generated class:

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use App\Enums\BookingType;

class BookingTypeCast implements CastsAttributes
{
    public function get($model, string $key, $value, array $attributes)
    {
        return BookingType::toName($value);
    }

    public function set($model, string $key, $value, array $attributes)
    {
        return $value;
    }
}
  1. Update Your Enum:

Ensure your enum has the toName method as you have already defined:

namespace App\Enums;

enum BookingType: int implements HasLabel
{
    case Booking = 0;
    case NotAvailable = 1;
    case Subscription = 2;

    public static function toName($value): string
    {
        return match ($value) {
            self::Booking->value => 'Booking',
            self::NotAvailable->value => 'NotAvailable',
            self::Subscription->value => 'Subscription',
        };
    }
}
  1. Use the Custom Cast in Your Model:

Finally, use the custom cast in your model:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Casts\BookingTypeCast;

class YourModel extends Model
{
    protected $casts = [
        'type' => BookingTypeCast::class,
    ];
}

With this setup, whenever you access the type attribute on your model, it will automatically be cast to the name of the enum value.

This approach keeps your code clean and leverages Laravel's custom casting feature to handle the conversion seamlessly.

1 like
Merklin's avatar

You can use this as example

 enum Statut: string

    case DRAFT = 'draft';
    case PENDING = 'pending';
    case IN_PROGRESS = 'in_progress';

   public function getLabel(): ?string
    {
        return match ($this) {
            self::DRAFT => 'Draft',
            self::PENDING => 'Pending',
            self::IN_PROGRESS => 'In Progress',
        };
    }

And then call it like Statut::DRAFT->getValue()

mr_reboot's avatar

I didn't like having to rewrite all the cases in the toName() function so I used this instead. Figured others finding this on Google like I did will find it useful:

    public static function toName($value): string
    {
        return self::from($value)->name;
    }

instead of this:

    public static function toName($value): string
    {
        return match ($value) {
            self::Booking->value => 'Booking',
            self::NotAvailable->value => 'NotAvailable',
            self::Subscription->value => 'Subscription',
        };
    }

https://www.php.net/manual/en/backedenum.from.php

ivqonsanada's avatar

@mr_reboot yes, already not use that approach, instead i make custom enum command and the end result would be like this

here i use more flexible approach to the name like "InProgress" to "In Progress" or if the name somehow different than the enum name itself

Please or to participate in this conversation.