phil / enums
Zero-dependency helper traits and attributes for PHP enums: case names and values, comparisons, from()/tryFrom() on pure enums and fromName(), static case access, and metadata attached to cases by attributes, with PHPStan extensions that type them
Requires
- php: >=8.5
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^13.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Traits and attributes that make PHP enums easier to list, compare, describe and group into sets.
phil/enums adds what native enums leave out. It reads the cases as names, values or options, and counts, filters,
groups, sorts and draws them. It compares cases and walks them in order, finds a case by name or parses it
leniently, and tells whether the enum is pure or backed. Attributes attach metadata to cases, such as a label, a
description, a group or a weight, and EnumSet and EnumMap hold cases in sets and maps.
It is for PHP developers whose enums carry more than a list of cases. It does not validate input, map enums to a
database or a form, or translate labels: it only makes the enum itself more useful. In a Symfony application,
phil/enums-bundle adds translation, forms, validation, Twig, Doctrine and API contracts on top of it.
It is a plain PHP library with no package dependency, usable in any code. Each trait adds public methods to the enum's API, so an enum uses only the traits it needs. PHPStan extensions type the methods the traits add and check required metadata.
Status
| Part | State |
|---|---|
| Traits: invocable, nameable, valuable, selectable, string-selectable, comparable, fromamble, metadatable, self-awareable, collectable, enumerable | Implemented and tested |
Metadata: Meta, Description, Group, Label, AbstractMetaProperty, meta properties declared by traits |
Implemented and tested |
| PHPStan extensions: static case calls, metadata accessors | Implemented |
Operations on the cases: CaseCollection — count, first and last, filter, reject, only and except, whereMeta(), sorts, map |
Implemented and tested |
| Metadata read once per enum and per case, kept for the process | Implemented and tested |
Grouping, partition, keyBy(), pluck(), weighted random() |
Implemented and tested |
EnumSet (set operations, bitmasks) and total EnumMap |
Implemented and tested |
Ordinals, parse() with #[Alias], #[DefaultCase], deprecated cases |
Implemented and tested |
#[TransitionsTo] and AsStatefulEnumTrait |
Implemented and tested |
SortDirection, shared by sorts, queries and SQL |
Implemented and tested |
EnumSet::fromValues(), EnumMap::fromPartial(), #[BitFlags] |
Implemented and tested |
#[RequiredMeta]: PHPStan rule and run-time check |
Implemented and tested |
| PHPStan rules of enum declarations and stored ordinals | Implemented, checked by the analysis of the fixtures |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, installing, the aggregate trait, and when to prefer single traits. |
| Values, names and options | __invoke() and static case calls, names(), values(), options() and stringOptions(). |
| Operations | Counting, first and last, filtering by callback or meta property, grouping, sorting, random draws, and the immutable CaseCollection. |
| Sets and maps | EnumSet, its set operations and bitmasks; the total EnumMap. |
| Order, parsing, defaults and transitions | Ordinals, parse() and #[Alias], #[DefaultCase], #[TransitionsTo], deprecated cases. |
| Comparison | is(), isNot(), in(), notIn(), has(), doesntHave(), equalsOneOf(), notEqualsOneOf(). |
| Lookup by name | from() and tryFrom() for pure enums, fromName() and tryFromName() for every enum. |
| Metadata | Attaching values to cases, writing meta properties, accessors, fromMeta(), traits that declare meta properties, the shipped properties, required metadata. |
| Self-awareness | isPure(), isBacked(), isBackedByInteger(), isBackedByString(). |
| PHPStan | Including the extensions, what they type, and the rules: required metadata, declarations, stored ordinals. |
| Extension points | The ports, arguments and data an application chooses or replaces. |
| Testing | The library's tests and mutation bar, and how to test your enums. |
| Reference | Every type of the library, with its role. |
Quick start
composer require phil/enums
use Phil\Enums\Attribute\Label; use Phil\Enums\Attribute\Meta; use Phil\Enums\Traits\AsMetadatableEnumTrait; use Phil\Enums\Traits\AsValuableEnumTrait; #[Meta(Label::class)] enum Status: string { use AsMetadatableEnumTrait; use AsValuableEnumTrait; #[Label('Draft')] case DRAFT = 'draft'; #[Label('Published')] case PUBLISHED = 'published'; } Status::values(); // ['draft', 'published'] Status::PUBLISHED->label(); // 'Published'
Upgrading from ph-il/enums
This package was published as ph-il/enums up to 0.2.2, and is phil/enums from 0.3.0 on; ph-il/enums is
abandoned in its favour. The namespace stays Phil\Enums: replace the requirement with composer remove ph-il/enums
then composer require phil/enums, and read the changelog for the changes of 0.3.0.
Requirements
PHP 8.5 or later and ext-mbstring; PHPStan 2 for the extensions.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.