eclipxe / enum
基于 Brent Roose 的 enum 理念 https://stitcher.io/blog/php-enums
Requires
- php: >=7.2
Requires (Dev)
- phpunit/phpunit: ^8.5
This package is auto-updated.
Last update: 2024-09-03 14:32:55 UTC
README
基于 Brent Roose 的 enum 理念 https://stitcher.io/blog/php-enums
阅读了关于 PHP Enums from Brent Roose 的文章,并回顾了在 spatie/enum 上所做的实现,我觉得它超出了我的预期。也许 spatie/enum 版本 1.0 更接近我所需要的。
因此,我创建了这个关于相同概念的无框架实现库。
截至 PHP 8.1,枚举是语言的一部分,这意味着这个库将不再需要。阅读 PHP 文档 https://php.ac.cn/manual/en/language.enumerations.php 并适应您的代码。PHP 枚举和此库中的对象之间的一大区别是,本机 PHP 枚举不能使用魔术方法 __toString
(它们不是 Stringable
),而此库中的枚举是。
安装
使用 composer,使用以下命令安装
composer require eclipxe/enum
使用方法
其他语言中的 Enum 在代码中是 TEXT
,在值中是 INTEGER
。
有两个有意义的信息:索引(integer
)和值(string
)。
此库提供了一个 Eclipxe\Enum
抽象类 供扩展。值是该方法的名称,如声明在 docblock 中。索引是 docblock 中的位置(从零开始)。
值一个接一个地注册,采用重写的值或方法的名称。
索引一个接一个地注册,采用重写的索引或已注册的最大值加 1。
枚举示例
<?php /** * This is a common use case enum sample * source: tests/Fixtures/Stages.php * * @method static self created() * @method static self published() * @method static self reviewed() * @method static self purged() * * @method bool isCreated() * @method bool isPublished() * @method bool isReviewed() * @method bool isPurged() */ final class Stages extends Eclipxe\Enum\Enum { }
实例创建
您可以使用带值构造函数、带索引构造函数或静态方法名称从值创建新实例。
<?php use Eclipxe\Enum\Tests\Fixtures\Stages; // create from value $purged = new Stages('purged'); // create from index $purged = new Stages(3); // create from an object that can be converted to string and contains the value $other = new Stages($purged); // create from static method $purged = Stages::purged(); // create from static method is not case-sensitive as methods are not $purged = Stages::{'PURGED'}(); // throws a BadMethodCallException because foobar is not part of the enum $purged = Stages::{'FOOBAR'}();
列出所有选项
Enum 暴露的唯一静态方法是 Enum::toArray(): array
,它将注册的可能值的列表导出为索引和值的数组。
<?php use Eclipxe\Enum\Tests\Fixtures\Stages; var_export(Stages::toArray()); /* [ 0 => 'created', 1 => 'published', 2 => 'reviewed', 3 => 'purged', ] */
检查实例是否为特定类型
使用方法 is<name>()
将其与特定值进行比较。
您必须在 docblock 中定义这些方法,以便您的 IDE 或代码分析器检测您正在执行的操作。
<?php use Eclipxe\Enum\Tests\Fixtures\Stages; $stage = Stages::purged(); $stage->isPurged(); // true $stage->isPublished(); // false $stage->{'isSomethingElse'}(); // false, even when SomethingElse is not defined $stage->{'SomethingElse'}(); // throw BadMethodCallException
或使用弱比较(相等,非身份)
<?php use Eclipxe\Enum\Tests\Fixtures\Stages; $stage = Stages::purged(); var_export($stage === Stages::purged()); // false, is not the same identity var_export($stage == Stages::purged()); // true var_export($stage == Stages::published()); // false var_export($stage->value() === Stages::purged()->value()); // true (compare using value) var_export($stage->index() === Stages::purged()->index()); // true (compare using index)
重写值或索引
您可以通过重写方法 overrideValues()
或 overrideIndices()
来重写值或索引。
规则
- 返回
array
键必须是 docblock 部分中定义的方法的名称(区分大小写)。 - 如果重写的值是
null
,则不会重写。 - 当重写值时,如果之前存在值,则将抛出
ValueOverrideException
。 - 当重写索引时,如果之前存在值,则将抛出
IndexOverrideException
。
<?php /** * This is an enum case where names and values are overridden * * @method static self monday() * @method static self tuesday() * @method static self wednesday() * @method static self thursday() * @method static self friday() * @method static self saturday() * @method static self sunday() */ final class WeekDays extends \Eclipxe\Enum\Enum { protected static function overrideValues(): array { return [ 'monday' => 'Monday', 'tuesday' => 'Tuesday', 'wednesday' => 'Wednesday', 'thursday' => 'Thursday', 'friday' => 'Friday', 'saturday' => 'Saturday', 'sunday' => 'Sunday', ]; } protected static function overrideIndices(): array { return [ 'monday' => 1, ]; } }
这将定义这些 array<index, value>
,使用静态方法 WeekDays::toArray()
获取
[ 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday', ];
请记住,枚举创建取决于注册的值和索引,如果使用了无效的值或索引,则会抛出异常
<?php use Eclipxe\Enum\Tests\Fixtures\WeekDays; new WeekDays(0); // throws IndexNotFoundException new WeekDays(1); // WeekDays {value: 'Monday', index: 1} new WeekDays('sunday'); // throws ValueNotFoundException (it is case-sensitive) new WeekDays('Sunday'); // WeekDays {value: 'Sunday', index: 7}
扩展
当创建扩展其他枚举的枚举时,父枚举在索引和值方面具有优先级。您不能覆盖前一个类中的索引或值。
我建议您将您的枚举类声明为 final
以禁用扩展。
如果使用类扩展,不要使用@method static self name()
语法,而是使用@method static static name()
语法,以便帮助分析工具。
请参阅以下示例:tests/Fixtures/ColorsBasic.php
、tests/Fixtures/ColorsExtended.php
和tests/Fixtures/ColorsExtendedWithBlackAndWhite.php
。
异常
由本包抛出的异常实现了空接口Eclipxe\Enum\Exceptions\EnumExceptionInterface
。
PHP 支持
此库至少与PHP 支持版本兼容,并具有活跃的支持。请尽量使用 PHP 的全部潜力。
我们遵循语义化版本控制。在主版本上,我们不会引入任何向后不兼容的更改。
内部类(使用@internal
注解)不属于此协议,因为它们必须仅存在于本项目内部。请不要在您的项目中使用它们。
贡献
欢迎贡献!请阅读CONTRIBUTING以获取详细信息,并别忘了查看TODO和CHANGELOG文件。
版权和许可
eclipxe/enum
库版权所有© Carlos C Soto,许可使用MIT许可证(MIT)。请参阅LICENSE获取更多信息。