PHPackages                             fab2s/enumerate - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. fab2s/enumerate

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

fab2s/enumerate
===============

Enumerate, a nice boost to your enums

0.0.1(1y ago)21.8k↓38.9%1MITPHPPHP ^8.1CI passing

Since Mar 16Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/fab2s/Enumerate)[ Packagist](https://packagist.org/packages/fab2s/enumerate)[ Docs](https://github.com/fab2s/Enumerate)[ RSS](/packages/fab2s-enumerate/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (2)Versions (2)Used By (1)

Enumerate
=========

[](#enumerate)

[![QA](https://github.com/fab2s/Enumerate/actions/workflows/qa.yml/badge.svg)](https://github.com/fab2s/Enumerate/actions/workflows/qa.yml) [![CI](https://github.com/fab2s/Enumerate/actions/workflows/ci.yml/badge.svg)](https://github.com/fab2s/Enumerate/actions/workflows/ci.yml) [![codecov](https://camo.githubusercontent.com/423eb7d90b7cbcb8621bea1a4fec08056f644cd7b469f887154bf68a7405ef7f/68747470733a2f2f636f6465636f762e696f2f67682f66616232732f456e756d65726174652f67726170682f62616467652e7376673f746f6b656e3d4d34505a365a364d7155)](https://codecov.io/gh/fab2s/Enumerate) [![Packagist Version](https://camo.githubusercontent.com/116a62d617078dcc9e519abc279668ec891e58f3a695697ff6e2afd0a6986c4f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66616232732f656e756d6572617465)](https://packagist.org/packages/fab2s/Enumerate) [![PRs Welcome](https://camo.githubusercontent.com/7d9ed3c8f22eceb1711573169b1390cc0b1194467340dc815205060c162b5309/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f7374796c653d666c6174)](http://makeapullrequest.com) [![License](https://camo.githubusercontent.com/8506677bd6a136d59d20f93f5f4374db74739f85f7f9cb7aa3cb9df017bae2fc/687474703a2f2f706f7365722e707567782e6f72672f66616232732f456e756d65726174652f6c6963656e7365)](https://packagist.org/packages/fab2s/Enumerate)

A lightweight PHP library that makes native enums practical for real-world applications.

The Problem
-----------

[](#the-problem)

PHP 8.1 enums are powerful but have limitations that create friction in production code:

- **No `Stringable` support** - Can't use enums directly in string contexts
- **Strict type restrictions** - Can't safely instantiate from mixed input (HTTP requests, databases)
- **No inheritance** - Can't share behavior across related enums
- **Type mismatch pain** - `IntBackedEnum::tryFrom('1')` throws instead of returning null

The Solution
------------

[](#the-solution)

Enumerate provides a unified API to work with any enum type consistently:

```
// Safely instantiate from any input type
$status = Status::tryFromAny($request->get('status')); // string, int, null, or enum instance

// Get a serializable value from any enum
$value = $status->toValue(); // Works for Unit, String, and Int backed enums

// Compare across enum boundaries
$status->compares(LegacyStatus::Active); // true if values match
```

Installation
------------

[](#installation)

```
composer require fab2s/enumerate
```

**Requirements:** PHP 8.1+

Quick Start
-----------

[](#quick-start)

Add the trait to your enum:

```
use fab2s\Enumerate\EnumerateTrait;
use fab2s\Enumerate\EnumerateInterface;

enum Status: string implements EnumerateInterface
{
    use EnumerateTrait;

    case Pending = 'pending';
    case Active  = 'active';
    case Closed  = 'closed';
}
```

Now you can:

```
// From HTTP request (could be string, int, or null)
$status = Status::tryFromAny($request->input('status'));

// From database or JSON
$status = Status::fromAny($row['status']); // throws if invalid

// To database or JSON
$value = $status->toValue(); // 'active'
json_encode($status);        // '"active"'

// Validation
$status->equals('active', 'pending'); // true if matches any
```

API Reference
-------------

[](#api-reference)

### Instantiation Methods

[](#instantiation-methods)

MethodReturnsThrowsDescription`tryFromAny($value, $strict = true)``?static`-Safe instantiation from any type`fromAny($value, $strict = true)``static``InvalidArgumentException`Strict instantiation`tryFromName($name)``?static`-Match by case name`fromName($name)``static``InvalidArgumentException`Strict match by case name### Value Methods

[](#value-methods)

MethodReturnsDescription`toValue()``int|string`Get the backed value (or case name for UnitEnum)`jsonSerialize()``int|string`Same as `toValue()`, implements `JsonSerializable`### Comparison Methods

[](#comparison-methods)

MethodReturnsDescription`equals(...$values)``bool`Strict match against provided values`compares(...$values)``bool`Loose match, allows cross-enum comparison by value### Type Inspection (Static Helper Only)

[](#type-inspection-static-helper-only)

MethodReturnsDescription`Enumerate::getType($enum)``?string`Returns `'string'`, `'int'`, or `null``Enumerate::isStringBacked($enum)``bool`Check if string-backed`Enumerate::isIntBacked($enum)``bool`Check if int-backed`Enumerate::isBacked($enum)``bool`Check if backed (not UnitEnum)Detailed Usage
--------------

[](#detailed-usage)

### Safe Instantiation with `tryFromAny`

[](#safe-instantiation-with-tryfromany)

The native `tryFrom()` only accepts the exact backing type. `tryFromAny()` handles real-world input:

```
enum Priority: int implements EnumerateInterface
{
    use EnumerateTrait;

    case Low    = 1;
    case Medium = 2;
    case High   = 3;
}

// All return Priority::Medium
Priority::tryFromAny(2);
Priority::tryFromAny(Priority::Medium);

// All return null (no exception)
Priority::tryFromAny('2');     // string on int-backed
Priority::tryFromAny(null);
Priority::tryFromAny('invalid');
```

### Cross-Enum Matching

[](#cross-enum-matching)

When migrating between enum versions or comparing related enums, use non-strict mode:

```
enum LegacyRole: string {
    case Admin = 'admin';
    case User  = 'user';
}

enum Role: string implements EnumerateInterface
{
    use EnumerateTrait;

    case Admin     = 'admin';
    case User      = 'user';
    case Moderator = 'moderator';
}

// Strict mode (default): only accepts same enum type
Role::tryFromAny(LegacyRole::Admin);              // null
Role::tryFromAny(LegacyRole::Admin, strict: true); // null

// Non-strict mode: matches by value across enums
Role::tryFromAny(LegacyRole::Admin, strict: false); // Role::Admin
```

### Working with UnitEnums

[](#working-with-unitenums)

UnitEnums (no backing value) are matched by case name:

```
enum Color implements EnumerateInterface
{
    use EnumerateTrait;

    case Red;
    case Green;
    case Blue;
}

Color::tryFromAny('Red');   // Color::Red
Color::tryFromName('Red');  // Color::Red
Color::Red->toValue();      // 'Red' (case name as string)
json_encode(Color::Red);    // '"Red"'
```

### Comparison Methods

[](#comparison-methods-1)

```
enum Status: string implements EnumerateInterface
{
    use EnumerateTrait;

    case Draft     = 'draft';
    case Published = 'published';
    case Archived  = 'archived';
}

$status = Status::Published;

// equals: strict comparison, multiple values allowed
$status->equals('published');                    // true
$status->equals('draft', 'published');           // true (matches any)
$status->equals(Status::Published);              // true

// compares: allows cross-enum matching by value
$status->compares(OtherEnum::Published);         // true if values match
```

### Using the Static Helper

[](#using-the-static-helper)

All methods are also available via the `Enumerate` static class, useful when you can't modify the enum:

```
use fab2s\Enumerate\Enumerate;

// Works with any enum, even without the trait
Enumerate::tryFromAny(SomeEnum::class, $value);
Enumerate::toValue(SomeEnum::Case);
Enumerate::equals(SomeEnum::Case, 'value');
Enumerate::getType(SomeEnum::class); // 'string', 'int', or null
```

Real-World Examples
-------------------

[](#real-world-examples)

### Form Request Handling

[](#form-request-handling)

```
class UpdateOrderRequest extends FormRequest
{
    public function validated(): array
    {
        return [
            'status'   => OrderStatus::fromAny($this->input('status')),
            'priority' => Priority::tryFromAny($this->input('priority')) ?? Priority::Medium,
        ];
    }
}
```

### Database Model Casting

[](#database-model-casting)

```
class Order extends Model
{
    protected $casts = [
        'status' => OrderStatus::class,
    ];

    public function scopeActive($query)
    {
        return $query->whereIn('status', [
            OrderStatus::Pending->toValue(),
            OrderStatus::Processing->toValue(),
        ]);
    }
}
```

### API Response

[](#api-response)

```
return response()->json([
    'status' => $order->status, // Automatically serialized via JsonSerializable
]);
```

Why This Exists
---------------

[](#why-this-exists)

PHP enums prioritize type safety over practicality. While philosophically sound, this creates boilerplate in real applications where enums must interoperate with HTTP requests (always strings), databases, and JSON APIs.

Enumerate handles this complexity internally so you don't have to write defensive code everywhere enums cross system boundaries.

Contributing
------------

[](#contributing)

Contributions are welcome. Please open issues and submit pull requests.

License
-------

[](#license)

Enumerate is open-source software licensed under the [MIT license](http://opensource.org/licenses/MIT).

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance64

Regular maintenance activity

Popularity23

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

428d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7323989?v=4)[fab2s](/maintainers/fab2s)[@fab2s](https://github.com/fab2s)

---

Top Contributors

[![fab2s](https://avatars.githubusercontent.com/u/7323989?v=4)](https://github.com/fab2s "fab2s (7 commits)")

---

Tags

phpenum

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/fab2s-enumerate/health.svg)

```
[![Health](https://phpackages.com/badges/fab2s-enumerate/health.svg)](https://phpackages.com/packages/fab2s-enumerate)
```

###  Alternatives

[kongulov/interact-with-enum

Trait for convenient use of ENUM in PHP

3052.3k2](/packages/kongulov-interact-with-enum)[iteks/laravel-enum

A comprehensive Laravel package providing enhanced enum functionalities, including attribute handling, select array conversions, and fluent facade interactions for robust enum management in Laravel applications.

2516.7k](/packages/iteks-laravel-enum)[vjik/php-enum

PHP Enum Implementation

209.9k](/packages/vjik-php-enum)[ducks-project/spl-types

Polyfill Module for SplType PHP extension. This extension aims at helping people making PHP a stronger typed language and can be a good alternative to scalar type hinting. It provides different typehandling classes as such as integer, float, bool, enum and string

1032.4k](/packages/ducks-project-spl-types)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
