dasprid / enum
PHP 7.1 枚举实现
1.0.6
2024-08-09 14:30 UTC
Requires
- php: >=7.1 <9.0
Requires (Dev)
- phpunit/phpunit: ^7 || ^8 || ^9 || ^10 || ^11
- squizlabs/php_codesniffer: *
README
众所周知,PHP 缺少基本的枚举类型,忽略相对不完整的 SplEnum
实现,该实现仅作为 PECL 扩展提供。还有相当多的其他用户枚举实现,但它们都存在一个或多个妥协。这个库试图尽可能地填补这一空白。
用法
基础知识
核心是 DASPRiD\Enum\AbstractEnum
类,默认情况下,它将与任何其他枚举实现一样使用常量。第一个明显的区别是,你应该将所有常量定义为受保护的(这样外部类的人就不能读取它们,但 AbstractEnum
仍然可以这样做)。另一个更强大的区别是,对于简单的枚举,常量的值根本不重要。让我们看看一个简单的例子
use DASPRiD\Enum\AbstractEnum; /** * @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 WeekDay extends AbstractEnum { protected const MONDAY = null; protected const TUESDAY = null; protected const WEDNESDAY = null; protected const THURSDAY = null; protected const FRIDAY = null; protected const SATURDAY = null; protected const SUNDAY = null; }
如果您需要提供常量用于内部使用或公共使用,您可以将其标记为私有或公共,在这种情况下,枚举将忽略它们,只考虑受保护的常量作为有效值。如您所见,我们特别在类级别文档块中定义了生成的魔法方法,因此任何使用此类的人都会自动在他们的 IDE 中获得正确的自动完成。现在,既然您已经定义了枚举,您可以使用它就像这样
function tellItLikeItIs(WeekDay $weekDay) { switch ($weekDay) { case WeekDay::MONDAY(): echo 'Mondays are bad.'; break; case WeekDay::FRIDAY(): echo 'Fridays are better.'; break; case WeekDay::SATURDAY(): case WeekDay::SUNDAY(): echo 'Weekends are best.'; break; default: echo 'Midweek days are so-so.'; } } tellItLikeItIs(WeekDay::MONDAY()); tellItLikeItIs(WeekDay::WEDNESDAY()); tellItLikeItIs(WeekDay::FRIDAY()); tellItLikeItIs(WeekDay::SATURDAY()); tellItLikeItIs(WeekDay::SUNDAY());
更复杂示例
当然,所有枚举都是单例,不可克隆或序列化。因此,您可以确信同一类型的实例始终只有一个。当然,常量的值并不完全无用,让我们看看一个更复杂的例子
use DASPRiD\Enum\AbstractEnum; /** * @method static self MERCURY() * @method static self VENUS() * @method static self EARTH() * @method static self MARS() * @method static self JUPITER() * @method static self SATURN() * @method static self URANUS() * @method static self NEPTUNE() */ final class Planet extends AbstractEnum { protected const MERCURY = [3.303e+23, 2.4397e6]; protected const VENUS = [4.869e+24, 6.0518e6]; protected const EARTH = [5.976e+24, 6.37814e6]; protected const MARS = [6.421e+23, 3.3972e6]; protected const JUPITER = [1.9e+27, 7.1492e7]; protected const SATURN = [5.688e+26, 6.0268e7]; protected const URANUS = [8.686e+25, 2.5559e7]; protected const NEPTUNE = [1.024e+26, 2.4746e7]; /** * Universal gravitational constant. * * @var float */ private const G = 6.67300E-11; /** * Mass in kilograms. * * @var float */ private $mass; /** * Radius in meters. * * @var float */ private $radius; protected function __construct(float $mass, float $radius) { $this->mass = $mass; $this->radius = $radius; } public function mass() : float { return $this->mass; } public function radius() : float { return $this->radius; } public function surfaceGravity() : float { return self::G * $this->mass / ($this->radius * $this->radius); } public function surfaceWeight(float $otherMass) : float { return $otherMass * $this->surfaceGravity(); } } $myMass = 80; foreach (Planet::values() as $planet) { printf("Your weight on %s is %f\n", $planet, $planet->surfaceWeight($myMass)); }