Skip to content

Repository files navigation

php-enum-utils

The missing toolkit for PHP 8.2+ native enums.

PHPStan Level 9License: MIT

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.

Installation

composer require kexxt/enum-utils

Requires PHP 8.2+.

Quick Start

useKexxt\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']

Custom Labels

By default, case names are humanized (SCREAMING_SNAKETitle Case, PascalCaseTitle Case). For custom labels, implement the HasLabels interface:

useKexxt\EnumUtils\Contracts\HasLabels;
useKexxt\EnumUtils\EnumUtilsTrait;
enum Color: stringimplements HasLabels
{
use EnumUtilsTrait;
case Red = 'red';
case DarkBlue = 'dark_blue';
publicfunctionlabel(): string
{
returnmatch ($this) {
self::Red => 'Red',
self::DarkBlue => 'Dark Blue',
};
}
}
Color::labels(); // ['red' => 'Red', 'dark_blue' => 'Dark Blue']

API Reference

EnumUtilsTrait

Add use EnumUtilsTrait; to any BackedEnum.

MethodReturnsDescription
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)staticFind case by label (throws ValueError)
tryFromLabel(string)?staticFind case by label (returns null)
randomCase()staticRandom case
toJsonValue()string|intBacking value (instance method)
fromJsonValue(string|int)staticCreate from backing value
jsonSerialize()string|intJsonSerializable implementation
collect()EnumCollectionCollection of all cases

EnumCollection

$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();

Validation

Standalone validation rule — no framework required:

useKexxt\EnumUtils\Validation\EnumValidationRule;
$rule = newEnumValidationRule(Status::class);
$rule->validate('active'); // true$rule->validate('invalid'); // false$rule->message(); // "The value must be one of: active, inactive, pending_review."

Laravel Integration

Cast Eloquent attributes to enums:

useKexxt\EnumUtils\Integration\Laravel\EnumCast;
class Order extends Model
{
protected$casts = [
'status' => EnumCast::class . ':' . Status::class,
];
}
$order->status; // Status::Active$order->status = Status::Inactive;

Symfony / Doctrine Integration

Create a custom DBAL type for your enum:

useKexxt\EnumUtils\Integration\Doctrine\AbstractEnumType;
class StatusType extends AbstractEnumType
{
protectedfunctiongetEnumClass(): string
{
return Status::class;
}
publicfunctiongetName(): string
{
return'status_enum';
}
}
// Register in Doctrine config:// doctrine:// dbal:// types:// status_enum: App\DBAL\StatusType

Migrating from myclabs/php-enum

myclabs/php-enumphp-enum-utils
class Status extends Enumenum 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.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Write tests for your changes
  4. Ensure all checks pass:
    composer test# Pest tests
    composer analyse # PHPStan level 9
    composer lint # PHP CS Fixer
  5. Commit with conventional commits: feat:, fix:, test:, docs:
  6. Open a pull request

License

MIT — see LICENSE.

About

The missing toolkit for PHP 8.2+ native enums — select arrays, labels, validation, and more

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages