Skip to content

ndcorder/php-enum-utils

Repository files navigation

php-enum-utils

The missing toolkit for PHP 8.2+ native enums.

PHPStan Level 9 License: 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

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

Custom Labels

By default, case names are humanized (SCREAMING_SNAKETitle Case, PascalCaseTitle 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']

API Reference

EnumUtilsTrait

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

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:

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."

Laravel Integration

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;

Symfony / Doctrine Integration

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

Migrating from myclabs/php-enum

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.

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

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages