patchlevel / enum
Small lightweight library to create enum in PHP without SPLEnum and strict comparisons allowed
Installs: 19 648
Dependents: 0
Suggesters: 0
Security: 0
Stars: 9
Watchers: 3
Forks: 1
Open Issues: 8
Requires
- php: ^7.4|^8.0
- ext-json: ^7.4|^8.0
Requires (Dev)
- infection/infection: ^0.20.2
- patchlevel/coding-standard: ^1.0.0
- phpstan/phpstan: ^0.12.58
- phpunit/phpunit: ^9.4.4
- symfony/var-dumper: ^5.2.0
- vimeo/psalm: ^4.3.1
This package is auto-updated.
Last update: 2023-10-04 13:17:55 UTC
README
enum
Small lightweight library to create enum in PHP without SPLEnum and strict comparisons allowed.
dislcaimer
For project that are build on PHP >=8.1 please use the language build in Enums described in this rfc: https://wiki.php.net/rfc/enumerations This library should not be needed anymore and will not support PHP >8.1.
installation
composer require patchlevel/enum
declaration
First of all you have to define your enum.
To do this, you have to inherit from the Enum
class, create a few constants (the value must be unique and a string)
and define methods that return an enum representation.
Here is an example:
<?php declare(strict_types=1); namespace Patchlevel\Enum\Example; use Patchlevel\Enum\Enum; /** * @psalm-immutable */ final class Status extends Enum { private const CREATED = 'created'; private const PENDING = 'pending'; private const RUNNING = 'running'; private const COMPLETED = 'completed'; public static function created(): self { return self::get(self::CREATED); } public static function pending(): self { return self::get(self::PENDING); } public static function running(): self { return self::get(self::RUNNING); } public static function completed(): self { return self::get(self::COMPLETED); } }
self::get()
ensures that exactly one instance of a representation really exists
so that strict comparisons can be used without problems.
Alternatively, you can inherit the ExtendedEnum
, which comes with a few conveniences,
more about this under ExtendedEnum.
api
work with enum
<?php declare(strict_types=1); namespace Patchlevel\Enum\Example; $status = Status::completed(); if ($status === Status::completed()) { echo "That's working"; } // or use as typehint function isFinished(Status $status): bool { return $status === Status::completed(); } echo isFinished($status) ? 'yes' : 'no'; // or with the new php8.0 match feature: $message = match ($status) { Status::created() => 'Process created', Status::pending() => 'Process pending', Status::running() => 'Process running', Status::completed() => 'Process completed', default => 'unknown status', }; echo $message; // Process completed
Strict comparisons are not a problem as it ensures that there is only one instance of a certain value.
fromString
You can create an enum from a string. It is checked internally whether the value is valid,
otherwise an InvalidValue
exception is thrown.
$status = Status::fromString('pending'); if ($status === Status::pending()) { echo 'it works'; }
toString
The other way around, an enum can also be converted back into a string.
$status::completed(); echo $status->toString(); // completed
equals
The Equals method is just a wrapper for $a === $b
.
$status = Status::completed(); $status->equals(Status::pending()); // false
isValid
isValid can be used to check whether the transferred value is valid. The return value is a boolean.
Status::isValid('foo'); // false Status::isValid('completed'); // true
values
You can also get all Enum instances.
$instances = Status::values(); foreach ($instances as $instance) { echo $instance->toString(); // completed, pending, ... }
keys
Or all keys.
$keys = Status::keys(); foreach ($keys as $key) { echo $key; // completed, pending, ... }
extended enum
Alternatively, it can also extend from ExtendedEnum
.
This implementation also provides other features mostly magic methods:
__toString
, __callStatic
and implementing \JsonSerializable
.
<?php declare(strict_types=1); namespace Patchlevel\Enum\Example; use Patchlevel\Enum\ExtendedEnum; /** * @psalm-immutable * @method static self CREATED() * @method static self PENDING() * @method static self RUNNING() * @method static self COMPLETED() */ final class Status extends ExtendedEnum { private const CREATED = 'created'; private const PENDING = 'pending'; private const RUNNING = 'running'; private const COMPLETED = 'completed'; }
__callStatic
With the magic method __callStatic
it is possible to create an Enum instance based only on the constant names.
So no extra method is needed to be defined. If the constant name doesn't exist in the enum a BadMethodCall
exception is thrown.
$status = Status::CREATED();
__toString
Just the magic method implementation of toString
.
$status = Status::CREATED(); echo (string)$status; // created
JsonSerializable
The ExtendedEnum already implements the method jsonSerialize
from the interface \JsonSerializable
.
This means that \json_encode
will automatically serialize the value in the right manner.
Beware that \json_decode
won't automatically decode it back into the enum. This job must be tackled
manually. See this example:
$status = Status::CREATED(); echo json_encode($status, JSON_THROW_ON_ERROR); // "created"