mediagone / types-enums
强类型枚举(类)用于模拟PHP 8.1的枚举。
0.1.5
2021-12-04 23:09 UTC
Requires
- php: ^7.4|^8.0
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^9.0
README
安装
此包需要 PHP 7.4+
将其作为Composer依赖项添加
$ composer require mediagone/types-enums
简介
使用常量表示可枚举值是不安全的,除非我们提供足够的检查来防止任何问题
class Article { public const STATUS_DRAFT = 0; public const STATUS_PUBLISHED = 1; private int $status; public function changeStatus(int $status) : void { // We need need to check if the provided status value is valid. if (! in_array($status, [Article::STATUS_DRAFT, Article::STATUS_PUBLISHED], true)) { throw new LogicException("Invalid status ($status)"); } $this->status = $status; } } $article->changeStatus(Article::STATUS_PUBLISHED); // valid $article->changeStatus(1); // valid but not safe $article->changeStatus(2); // invalid (and risky if there is no validity check in the method) class OtherClass { public const ANOTHER_INT_CONSTANT = 0; } $article->changeStatus(OtherClass::ANOTHER_INT_CONSTANT); // valid but senseless
使用强类型枚举代替PHP原始类型(int,string)可以在任何地方安全地类型提示它们,并确保您的数据有效,而无需在您的代码中添加任何检查。
遗憾的是,PHP在8.1之前没有提供原生的枚举,但可以使用类来模拟。
文档
简单用法
首先,创建一个枚举类,将您的可枚举值定义为私有常量
注意:将静态方法注释添加到您的类中,以在您的首选IDE中启用自动完成。
/** * @method static ArticleStatus DRAFT() * @method static ArticleStatus PUBLISHED() */ final class ArticleStatus extends EnumInt { private const DRAFT = 0; private const PUBLISHED = 1; }
现在,可以通过静态方法访问枚举值,这些方法返回一个ArticleStatus实例
ArticleStatus::DRAFT(); ArticleStatus::PUBLISHED(); // Strict comparisons are valid since methods always return the same instance ArticleStatus::PUBLISHED() === ArticleStatus::PUBLISHED(); // true ArticleStatus::DRAFT() === ArticleStatus::PUBLISHED(); // false
现在,您可以使用它作为常规的强类型属性
class Article { private ArticleStatus $status; public function changeStatus(ArticleStatus $status) : void { // No check needed because $status is always a valid value. $this->status = $status; } } $article->changeStatus(ArticleStatus::PUBLISHED()); // valid $article->changeStatus(1); // invalid
枚举信息
您可以通过使用->value和->name属性来访问枚举的底层值和名称
final class ArticleStatus extends EnumInt { private const DRAFT = 0; private const PUBLISHED = 1; } ArticleStatus::PUBLISHED()->value; // 1 ArticleStatus::PUBLISHED()->name; // "PUBLISHED"
序列化
由于PHP序列化机制不允许定义要恢复的实例,它完全破坏了库的工作方式和严格比较
$a = unserialize(serialize(ArticleStatus::PUBLISHED())); $b = ArticleStatus::PUBLISHED(); $a === $b; // false
这就是为什么对所有枚举类禁用了serialize()和unserialize()的原因。
如果您需要处理序列化,您必须手动存储枚举的值并在之后恢复它
$serializedValue = ArticleStatus::PUBLISHED()->value; // restore the enum $enum = ArticleStatus::from($serializedValue);
注意:不建议使用枚举名称进行序列化,因为代码重构可能会随时破坏它。
许可
Types Enums 在MIT许可下发布。请参阅LICENSE文件。