PHP Enum پیشرفته — backed enum، trait و الگوهای Laravel
Enum در PHP 8.1 magic number و string پراکنده را جمع کرد. سطح مقدماتی در PHP 8.3 بود — اینجا backed enum، رفتار روی case و یکپارچگی با Laravel را عمیق میکنیم.
Pure vs Backed Enum
enum PostStatus
{
case Draft;
case Published;
case Archived;
}
enum PostStatus: string
{
case Draft = 'draft';
case Published = 'published';
case Archived = 'archived';
}
Backed برای ذخیره در DB — migration ستون string یا tinyInteger.
متد روی Enum
enum PostStatus: string
{
case Draft = 'draft';
case Published = 'published';
public function label(): string
{
return match ($this) {
self::Draft => 'پیشنویس',
self::Published => 'منتشر شده',
};
}
public function isPublic(): bool
{
return $this === self::Published;
}
}
logic مرتبط با status کنار تعریف — Clean Code.
tryFrom و from
$status = PostStatus::tryFrom($request->input('status'));
if ($status === null) {
throw new InvalidArgumentException('Invalid status');
}
// from — exception اگر نامعتبر
$status = PostStatus::from('draft');
cases() و iterate
foreach (PostStatus::cases() as $case) {
echo $case->value;
}
$options = collect(PostStatus::cases())
->mapWithKeys(fn ($s) => [$s->value => $s->label()]);
برای select در Filament و validation Rule::enum(PostStatus::class).
Eloquent Cast
protected function casts(): array
{
return ['status' => PostStatus::class];
}
Eloquent Casts — خودکار backed enum.
Enum vs Value Object
مجموعه ثابت finite — enum. مقدار با validation پیچیده (Email) — Value Object.
trait روی Enum
trait HasLabels
{
abstract public function label(): string;
}
enum OrderStatus: string
{
use HasLabels;
case Pending = 'pending';
// label per case...
}
migration seed
$table->string('status')->default(PostStatus::Draft->value);
اشتباهات
- enum با ۵۰ case شبیه config — شاید DB table بهتر
- business logic سنگین داخل enum — Service/Action
- مقایسه با string خام بهجای enum
جمعبندی
Enum type-safe status و option. بعدی: Attributes. Strategy: الگوها.