spatie/enum
Obsolete: PHP 8.1+ has native enums (recommended). Spatie Enum provides strongly typed, object-based enums for older PHP versions, enabling IDE-friendly static analysis and refactoring. Define enums via @method annotations and call StatusEnum::draft().
Start by installing the package via Composer: composer require spatie/enum. Then create a simple enum by extending Spatie\Enum\Enum and defining static method calls via @method docblock annotations:
use Spatie\Enum\Enum;
/**
* @method static self draft()
* @method static self published()
*/
class PostStatus extends Enum
{
}
Use it immediately in type-hinted methods:
public function setStatus(PostStatus $status): void
{
$this->status = $status;
}
// Later
$post->setStatus(PostStatus::published());
First real-world use case: mapping database values (e.g., integers) to objects. Override values to match your schema:
protected static function values(): array
{
return ['draft' => 0, 'published' => 1];
}
Then hydrate from DB: PostStatus::from($dbValue).
⚠️ Critical note: Since this package is obsolete as of PHP 8.1 (native enums), only use this if stuck on PHP < 8.1. For new projects, prefer native enums.
Database Integration (non-Laravel): Use from()/tryFrom() for hydration and $enum->value for persistence. Consider a base enum class with shared logic (e.g., isActive()).
Type-Safe Assignment: Use constructor injection and method parameters with Enum type hints to prevent invalid states and enable IDE refactoring (rename, find usages).
Labels for UI: Override labels() to provide user-friendly names for dropdowns or validation messages:
protected static function labels(): array
{
return ['draft' => 'Draft (not ready)'];
}
PHPUnit Testing: Extend Spatie\Enum\Phpunit\EnumAssertions to assert enum type and validity:
$this->assertSameEnum(PostStatus::published(), $post->status);
$this->assertIsEnumValue(PostStatus::class, 'draft');
Faker Integration: Add FakerEnumProvider for test factories:
$faker->addProvider(new FakerEnumProvider($faker));
$status = $faker->randomEnum(PostStatus::class);
Laravel Projects: Use the companion package spatie/laravel-enum for built-in model casting ('status' => PostStatus::class) and request validation (Rule::in(PostStatus::values())).
value is read-only: You cannot modify the internal value — enforce validity only at construction time via from().
BadMethodCallException on invalid values: Using from('nonexistent') throws. Prefer tryFrom() when unsanitized input is used (e.g., query params).
Docblocks matter: IDE autocompletion/refactoring only works if you keep @method annotations synced with your static methods. Run composer test to guard against drift.
Closure for dynamic values/labels: Use closures when naming conventions can derive values/labels, e.g., fn($name) => str_replace('_', '-', $name).
Compare via equals(): Avoid ==/=== comparisons across different enum classes — always use $enum->equals($other) even if types match.
Avoid direct instantiation: new EnumClass(...) is discouraged outside hydration. Prefer from()/tryFrom() to prevent bypassing validation.
PHP version check: If your codebase targets PHP ≥8.1, stop using this package. Migrate to native enums (enum Status: int { case Draft = 1 }) for better performance and native language support.
How can I help you explore Laravel packages today?