DEV Community

Morcos Gad
Morcos Gad

Posted on • Updated on

New PHP Enum in Laravel

I've always been a fan of PHP Enum. I found an article https://medium.com/code16/how-to-use-the-new-php-enum-in-laravel-7e94515b9b4e explaining how to use it with laravel and wanted to share it with you.
PHP 8.1 introduced long awaited support for built-in Enums. There is no more need for custom solutions in your Laravel projects since Laravel with its 8.69 release has your back.
We’ll take a really simple example

namespace App\Enums;

enum BlogpostState: string
{
    case DRAFT = 'state_draft';
    case PUBLISHED = 'state_published';
}
Enter fullscreen mode Exit fullscreen mode

When creating your database

public function up()
{
    Schema::create('blogposts', function (Blueprint $table) {
        ...
        $table->string('state');
    });
}
Enter fullscreen mode Exit fullscreen mode

You can use the new casting in your Blogpost model and it allows your state model attribute to be casted to/from an Enum

namespace App\Models;

class Blogpost extends Model
{
    protected $casts = [
       'state' => BlogpostState::class,
    ];
}
Enter fullscreen mode Exit fullscreen mode

So for example you can now compare the state to the Enum directly

public function isPublished()
{
    return $this->state === BlogpostState::PUBLISHED;
}
Enter fullscreen mode Exit fullscreen mode

Then you’ll get

>>> dd($blogpost->state);
=> App\Enums\BlogpostState {
     +name: "DRAFT",
     +value: "state_draft",
   }

>>> dd($blogpost->state->value);
=> "state_draft"
Enter fullscreen mode Exit fullscreen mode

Also if you try to create or update a blogpost with an invalid state value, you’ll get an immediate PHP error

>>> $blogpost->update(['state' => 'unlisted']);
PHP Error:  "unlisted" is not a valid backing value for enum "App\Models\Enums\BlogpostState"
Enter fullscreen mode Exit fullscreen mode

The state’s enum can have methods

public function label(): string
{
    return match($this)
    {
      self::DRAFT => 'Draft...',
      self::PUBLISHED => 'Published!',
    };
}

>>> $blogpost->state->label();
=> "Draft..."
Enter fullscreen mode Exit fullscreen mode

Validation rule

namespace App\Http\Requests;

class BlogpostRequest extends FormRequest
{
    public function rules()
    {
        return [
            "state" => [
                 "required",
                 new Enum(BlogpostState::class)
            ],
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

Factory

namespace Database\Factories;

class BlogpostFactory extends Factory
{

    public function definition()
    {
        return [
            ...
            'state' => BlogpostState::DRAFT,
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

I hope you enjoyed the code.

Discussion (0)