Featured blog image
236 كلمة 2 دقيقة للقراءة

Laravel Enum ما هي وكيف تستخدمها في Laravel

لماذا أصبحت جزءًا أساسيًا في هندسة مشاريع Laravel الحديثة؟

الـ Enum هي ميزة قدمتها PHP منذ إصدار PHP 8.1، وتمنحك طريقة منظمة لتعريف مجموعة قيم ثابتة ككيان واحد بدل الاعتماد على نصوص (Strings) أو أعداد (Integers) متناثرة في المشروع. الهدف: كود أنظف، أقل أخطاء، وأسهل صيانة.


أولًا: لماذا Enums مهمة؟

1) القيم تصبح كيانات حقيقية داخل المشروع

قبل Enum كنت تتعامل مع نصوص عشوائية مثل 'pending'. الآن تتحول هذه القيم إلى نوع بيانات يمكن للـ IDE فهمه، مما يوفّر إكمال تلقائي ووقاية من الأخطاء.

<?php
enum OrderStatus: string {
    case PENDING = 'pending';
    case PROCESSING = 'processing';
    case COMPLETED = 'completed';
    case CANCELED = 'canceled';
}


2) منع الأخطاء الناتجة عن "magic strings"

الكتابة اليدوية للنصوص تؤدي لأخطاء إملائية يصعب تتبعها. Enum يجبرك على استخدام القيم المعروفة فقط.

// خطأ ممكن يحصل
if ($order->status === 'pendng') { /* خطأ */ }

// مع Enum - آمن وواضح
if ($order->status === OrderStatus::PENDING) {
    // منطق التنفيذ
}


3) تنظيم القيم في مكان واحد

تجمّع القيم في ملف Enum واحد يسهل البحث، التعديل، وإضافة قيم جديدة بدون تعديل أجزاء متعددة من الكود.

enum UserType: string {
    case ADMIN = 'admin';
    case CLIENT = 'client';
    case MARKETER = 'marketer';
}

ثانيًا: تكامل Enums مع Laravel — أمثلة عملية

1) Casting داخل الـ Model

أقوى تكامل: تحويل عمود القاعدة إلى Enum تلقائيًا عبر $casts. هذا يعني أن أي تعامل مع الحقل سيكون Enum وليس String.

class Order extends Model
{
    protected $casts = [
        'status' => OrderStatus::class,
    ];
}

// استخدام لاحق
if ($order->status === OrderStatus::COMPLETED) {
    // منطق
}


2) استخدام Enum داخل Controllers و Services

استخدم Enum عند التعيين والقراءة لتوضيح النية وتقليل الأخطاء.

$order->status = OrderStatus::PROCESSING;
$order->save();


3) Validation باستخدام Enum

Laravel يسمح بالتحقق من أن القيم المرسلة من العميل ضمن القيم المعتمدة في Enum.

$request->validate([
    'status' => ['required', new \Illuminate\Validation\Rules\Enum(OrderStatus::class)],
]);


4) استخدام Enum في Switch Cases

يجعل الشيفرة أنظف وأسهل للقراءة مقارنة بمقارنات نصية عشوائية.

switch ($order->status) {
    case OrderStatus::PENDING:
        // منطق الانتظار
        break;

    case OrderStatus::COMPLETED:
        // منطق الاكتمال
        break;
}


5) تعريف دوال داخل Enum

يمكن أن يحتوي Enum على دوال مساعدة (مثلاً Label أو CSS class) مما يحوّله لكيان ذكي يدير سلوكه.

enum OrderStatus: string
{
    case PENDING = 'pending';
    case COMPLETED = 'completed';

    public function label(): string
    {
        return match ($this) {
            self::PENDING => 'قيد الانتظار',
            self::COMPLETED => 'مكتمل',
        };
    }
}

// استخدام
echo $order->status->label();

ثالثًا: مقارنة سريعة — Enum vs Constants

  • Constants: مفيدة ولكنها نصوص/قيم ثابتة داخل كلاس، لا تدعم Type-safety أو طرق داخلية.
  • Enums: نوع بيانات، تدعم دوال داخلية، تعمل جيدًا مع الفاليديشن، والـ IDE قادر على تقديم مساعدة أفضل.
// Constants (أسلوب تقليدي)
class OrderStatuses {
    public const PENDING = 'pending';
    public const COMPLETED = 'completed';
}

// Enum (أنسب اليوم)
enum OrderStatus: string {
    case PENDING = 'pending';
    case COMPLETED = 'completed';
}

رابعًا: متى تستخدم Enum؟ متى لا؟

  • استخدم Enum عندما تكون لديك قيمة ثابتة بقوائم محددة: حالات الطلب، أدوار المستخدم، طرق الدفع، أنواع الإشعارات، إلخ.
  • لا تستخدم Enum لقيم ديناميكية تُدار من لوحة تحكم للمستخدم أو من قاعدة بيانات قابلة للتعديل من غير مطور.

خامسًا: نصائح عملية لتحسين جودة الكود باستخدام Enum

  • ضع Enums داخل مسار منظم مثل app/Enums.
  • استخدم Casting في الموديلات لتفادي المقارنات النصية المباشرة.
  • أضف دوال مساعدة داخل Enum (label, cssClass, toArray) لتوحيد المنطق العرضي.
  • استخدم Enum في الـ Validation لضمان سلامة البيانات الواردة من المستخدمين.
  • عند العمل مع API، فكّر في تحويل Enum إلى قيمة نصية أو رقمية صريحة في Resources.
// مثال: تحويل Enum لقيمة صالحة للـ API Resource
public function toArray($request)
{
    return [
        'id' => $this->id,
        'status' => $this->status->value, // 'pending', 'completed', ...
        'status_label' => $this->status->label(),
    ];
}

شارك الآن ؟
تواصل معي