Laravel Architecture

Replace Magic Strings with PHP 8 Backed Enums in Eloquent Models

Punyapal Shah 2 min read
edit this tip
Use PHP 8 Backed Enums to eliminate magic strings in database columns, query scopes, and form validation rules.

Hardcoding status strings like $order->status === 'pending' or User::where('role', 'admin') across multiple controllers makes refactoring difficult and introduces silent typo bugs that static analysis tools cannot catch.

PHP 8 Backed Enums provide type safety and IDE autocomplete.

Defining a Backed Enum

namespace App\Enums;

enum OrderStatus: string
{
    case PENDING    = 'pending';
    case PROCESSING = 'processing';
    case COMPLETED  = 'completed';
    case CANCELLED  = 'cancelled';

    public function label(): string
    {
        return match ($this) {
            self::PENDING    => 'Order Pending',
            self::PROCESSING => 'In Processing',
            self::COMPLETED  => 'Order Completed',
            self::CANCELLED  => 'Cancelled',
        };
    }
}

Casting in Eloquent Models

namespace AppModels;

use App\Enums\OrderStatus;
use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    protected function casts(): array
    {
        return [
            'status' => OrderStatus::class,
        ];
    }
}

Type-Safe Querying and Comparison

use App\Enums\OrderStatus;

// Type-safe query: No magic strings
$orders = Order::where('status', OrderStatus::PENDING)->get();

// Natural enum comparison
if ($order->status === OrderStatus::COMPLETED) {
    // Process fulfillment
}

Summary

  • Prevents typos and catches invalid status assignments during compilation.
  • Provides native casting with Eloquent models via casts().
  • Bundles domain display labels and helper methods directly inside Enum classes.
Tags: Laravel Enums PHP 8.1+ Clean Code
Share on X

// Found an issue or want to contribute a tip? github.com/MrPunyapal/tips