补丁级别 / 枚举
一个轻量级的库,用于在PHP中创建枚举,不使用SPLEnum,允许严格比较
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
枚举
一个轻量级的库,用于在PHP中创建枚举,不使用SPLEnum,允许严格比较。
免责声明
对于基于PHP >=8.1的项目,请使用此rfc中描述的内置枚举语言:https://wiki.php.net/rfc/enumerations 此库将不再需要,并且不会支持PHP >=8.1。
安装
composer require patchlevel/enum
声明
首先,您必须定义您的枚举。为此,您需要从《Enum》类继承,创建一些常量(值必须是唯一的字符串)并定义返回枚举表示的方法。以下是一个示例
<?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()
确保确实存在一个表示实例,以便可以无问题地使用严格比较。
或者,您可以继承ExtendedEnum
,它提供了一些便利,更多关于这一点在ExtendedEnum下讨论。
API
使用枚举
<?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
由于它确保只有一个特定值的实例,因此严格比较不会成为问题。
fromString
您可以从字符串创建一个枚举。内部会检查值是否有效,否则会抛出InvalidValue
异常。
$status = Status::fromString('pending'); if ($status === Status::pending()) { echo 'it works'; }
toString
相反,枚举也可以转换回字符串。
$status::completed(); echo $status->toString(); // completed
equals
Equals方法只是$a === $b
的包装。
$status = Status::completed(); $status->equals(Status::pending()); // false
isValid
isValid可以用来检查传递的值是否有效。返回值是一个布尔值。
Status::isValid('foo'); // false Status::isValid('completed'); // true
values
您还可以获取所有Enum实例。
$instances = Status::values(); foreach ($instances as $instance) { echo $instance->toString(); // completed, pending, ... }
keys
或所有键。
$keys = Status::keys(); foreach ($keys as $key) { echo $key; // completed, pending, ... }
扩展枚举
或者,它也可以扩展自ExtendedEnum
。此实现还提供了其他功能,主要是魔法方法:__toString
、__callStatic
和实现\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
通过魔法方法__callStatic
,您可以根据常量名称创建枚举实例。因此不需要定义额外的函数。如果枚举中不存在该常量名称,将抛出BadMethodCall
异常。
$status = Status::CREATED();
__toString
只是toString
的魔法方法实现。
$status = Status::CREATED(); echo (string)$status; // created
JsonSerializable
ExtendedEnum已经实现了接口\JsonSerializable
的jsonSerialize
方法。这意味着\json_encode
将自动以正确的方式序列化值。请注意,\json_decode
不会自动将其解码回枚举。这项工作必须手动完成。请参阅此示例
$status = Status::CREATED(); echo json_encode($status, JSON_THROW_ON_ERROR); // "created"