The missing toolkit for PHP 8.2+ native enums.
PHP 8.1 introduced native enums, but the ecosystem still relies on myclabs/php-enum for convenience methods. This zero-dependency package provides everything you need: select arrays for forms, label resolution, random selection, JSON helpers, validation, collection operations, and framework integrations.
composer require kexxt/enum-utilsRequires PHP 8.2+.
use Kexxt\EnumUtils\EnumUtilsTrait;
enum Status: string
{
use EnumUtilsTrait;
case Active = 'active';
case Inactive = 'inactive';
case PendingReview = 'pending_review';
}
Status::toSelectArray();
// ['active' => 'Active', 'inactive' => 'Inactive', 'pending_review' => 'Pending Review']
Status::fromLabel('Active'); // Status::Active
Status::tryFromLabel('Unknown'); // null
Status::randomCase(); // Status::Active or Status::Inactive or ...
Status::values(); // ['active', 'inactive', 'pending_review']By default, case names are humanized (SCREAMING_SNAKE → Title Case, PascalCase → Title Case). For custom labels, implement the HasLabels interface:
use Kexxt\EnumUtils\Contracts\HasLabels;
use Kexxt\EnumUtils\EnumUtilsTrait;
enum Color: string implements HasLabels
{
use EnumUtilsTrait;
case Red = 'red';
case DarkBlue = 'dark_blue';
public function label(): string
{
return match ($this) {
self::Red => 'Red',
self::DarkBlue => 'Dark Blue',
};
}
}
Color::labels(); // ['red' => 'Red', 'dark_blue' => 'Dark Blue']Add use EnumUtilsTrait; to any BackedEnum.
| Method | Returns | Description |
|---|---|---|
values() |
array<string|int> |
All backing values |
labels() |
array<value, label> |
Value-to-label map |
toSelectArray() |
array<value, label> |
Same as labels(), for HTML selects |
toRadioOptions() |
array<{value, label, name}> |
Radio/checkbox option data |
fromLabel(string) |
static |
Find case by label (throws ValueError) |
tryFromLabel(string) |
?static |
Find case by label (returns null) |
randomCase() |
static |
Random case |
toJsonValue() |
string|int |
Backing value (instance method) |
fromJsonValue(string|int) |
static |
Create from backing value |
jsonSerialize() |
string|int |
JsonSerializable implementation |
collect() |
EnumCollection |
Collection of all cases |
$collection = Status::collect();
$collection->filter(fn(Status $s) => $s !== Status::Inactive);
$collection->map(fn(Status $s) => $s->value);
$collection->contains(Status::Active); // true
$collection->diff($otherCollection);
$collection->toArray();
$collection->count();Standalone validation rule — no framework required:
use Kexxt\EnumUtils\Validation\EnumValidationRule;
$rule = new EnumValidationRule(Status::class);
$rule->validate('active'); // true
$rule->validate('invalid'); // false
$rule->message(); // "The value must be one of: active, inactive, pending_review."Cast Eloquent attributes to enums:
use Kexxt\EnumUtils\Integration\Laravel\EnumCast;
class Order extends Model
{
protected $casts = [
'status' => EnumCast::class . ':' . Status::class,
];
}
$order->status; // Status::Active
$order->status = Status::Inactive;Create a custom DBAL type for your enum:
use Kexxt\EnumUtils\Integration\Doctrine\AbstractEnumType;
class StatusType extends AbstractEnumType
{
protected function getEnumClass(): string
{
return Status::class;
}
public function getName(): string
{
return 'status_enum';
}
}
// Register in Doctrine config:
// doctrine:
// dbal:
// types:
// status_enum: App\DBAL\StatusType| myclabs/php-enum | php-enum-utils |
|---|---|
class Status extends Enum |
enum Status: string |
new Status('active') |
Status::from('active') |
Status::toArray() |
Status::toSelectArray() |
Status::keys() |
array_keys(Status::labels()) |
$status->getKey() |
$status->name |
$status->getValue() |
$status->value |
$status->equals($other) |
$status === $other |
Status::isValid('active') |
Status::tryFrom('active') !== null |
Status::search('active') |
Status::from('active') |
The main difference: native PHP enums are first-class language constructs with type safety, exhaustive match support, and no reflection overhead for basic operations.
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Write tests for your changes
- Ensure all checks pass:
composer test # Pest tests composer analyse # PHPStan level 9 composer lint # PHP CS Fixer
- Commit with conventional commits:
feat:,fix:,test:,docs: - Open a pull request
MIT — see LICENSE.