dasprid/enum

PHP 7.1 枚举实现

维护者

详细信息

github.com/DASPRiD/Enum

源代码

问题

安装次数: 80,093,942

依赖: 9

建议者: 0

安全: 0

星标: 335

关注者: 4

分支: 13

开放问题: 0

1.0.6 2024-08-09 14:30 UTC

This package is auto-updated.

Last update: 2024-09-09 14:49:57 UTC


README

Build Status Coverage Status Latest Stable Version Total Downloads License

众所周知,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));
}