Enum در PHP 8.1 به بعد، مجموعهای از حالتهای مشخص را بهصورت یک نوع مستقل تعریف میکند. در لاراول میتوان از آن برای وضعیت رکورد، نقش یا نام مجوز استفاده کرد. مهم است بین خودِ case، نام آن و مقدار ذخیرهشدنی تفاوت بگذاریم.
📩 با عضویت در خبرنامه، جدیدترین مطالب و آموزشها را مستقیم در ایمیل خود دریافت کنید.
نام و مقدار در Backed Enum
<?php
namespace App\Enums;
enum Expenses: string
{
case CREATE_EXPENSE = 'create-expense';
case DELETE_EXPENSE = 'delete-expense';
case APPROVE_EXPENSE = 'approve-expense';
public function label(): string
{
return match ($this) {
self::CREATE_EXPENSE => 'ایجاد هزینه',
self::DELETE_EXPENSE => 'حذف هزینه',
self::APPROVE_EXPENSE => 'تأیید هزینه',
};
}
}
// Expenses::CREATE_EXPENSE is an enum case.
// Expenses::CREATE_EXPENSE->name is "CREATE_EXPENSE".
// Expenses::CREATE_EXPENSE->value is "create-expense".
Enum معمولی ویژگی name دارد؛ Backed Enum علاوه بر آن value هم دارد که رشته یا عدد صحیح است. اگر مقادیر پایگاه داده عددی هستند، میتوانید نوع پشتوانه را int انتخاب کنید. نام case را با مقدار پشتوانه اشتباه نگیرید.
استفاده در Gate و Blade
نام مجوز باید با Gate یا Policy تعریفشده در برنامه مطابقت داشته باشد. داشتن Enum بهتنهایی مجوز دسترسی ایجاد نمیکند.
use App\Enums\Expenses;
use Illuminate\Support\Facades\Gate;
Gate::authorize(Expenses::CREATE_EXPENSE->value);
در Blade نیز میتوان از نام کامل کلاس استفاده کرد:
{{ \App\Enums\Expenses::APPROVE_EXPENSE->label() }}
تبدیل مقدار و نگهداری در مدل
use App\Enums\Expenses;
$permission = Expenses::tryFrom('create-expense');
if ($permission !== null) {
echo $permission->label();
}
// Inside the Eloquent model:
protected function casts(): array
{
return ['permission' => Expenses::class];
}
در صورت نبودن مقدار متناظر، tryFrom() مقدار null برمیگرداند؛ from() خطای ValueError میدهد. برای ورودی بیرونی، این حالت را مدیریت کنید. ستون و دادههای موجود مدل نیز باید با مقدارهای Enum سازگار باشند.
آیا فراخوانی استاتیک لازم است؟
نگارش Expenses::CREATE_EXPENSE() رفتار پیشفرض Enum نیست. میتوان با کد سفارشی و __callStatic() چنین میانبری ساخت، اما خطای نام متد در آن به زمان اجرا منتقل میشود. استفادهٔ مستقیم از case و value معمولاً سادهتر و برای ابزارهای تحلیل کد روشنتر است. همچنین اصطلاح Invokable به پیادهسازی __invoke() اشاره دارد و با این میانبر استاتیک یکسان نیست.
مرجع: مستندات رسمی؛ نسخهٔ مستندات را با نسخهٔ پروژهٔ خود تطبیق دهید.

