PHP 枚举实现

1.0.0 2022-08-07 17:54 UTC

This package is auto-updated.

Last update: 2024-09-09 08:57:15 UTC


README

请使用PHP 8.1+内置的枚举。

这是PHP 5的https://github.com/DASPRiD/Enum的移植版本,因为仍有一些服务/应用程序在生产中使用旧的PHP,遗憾的是。但他们也想使用一点枚举。

众所周知,在版本8.1之前,PHP缺少基本枚举类型,忽略相对不完整的SplEnum实现,该实现仅作为PECL扩展提供。还有许多其他的用户空间枚举实现,但它们都有这样或那样的妥协。这个库尝试尽可能填补这个空白(在版本8.1之前)。

使用方法

基础

在其核心,有一个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 static $MONDAY;
    protected static $TUESDAY;
    protected static $WEDNESDAY;
    protected static $THURSDAY;
    protected static $FRIDAY;
    protected static $SATURDAY;
    protected static $SUNDAY;
}

如果你需要提供常量供内部或公共使用,你可以将它们标记为私有或公共,在这种情况下,枚举将忽略它们,只考虑受保护的常量作为有效值。如你所见,我们特别在类级别的文档块中定义了生成的魔术方法,这样任何使用此类的用户都将自动在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 static $MERCURY = [3.303e+23, 2.4397e6];
    protected static $VENUS = [4.869e+24, 6.0518e6];
    protected static $EARTH = [5.976e+24, 6.37814e6];
    protected static $MARS = [6.421e+23, 3.3972e6];
    protected static $JUPITER = [1.9e+27, 7.1492e7];
    protected static $SATURN = [5.688e+26, 6.0268e7];
    protected static $URANUS = [8.686e+25, 2.5559e7];
    protected static $NEPTUNE = [1.024e+26, 2.4746e7];

    /**
     * Universal gravitational constant.
     */
    private static $G = 6.67300E-11;

    /**
     * Mass in kilograms.
     *
     * @var float
     */
    private $mass;

    /**
     * Radius in meters.
     *
     * @var float
     */
    private $radius;

    /**
     * @param float $mass
     * @param float $radius
     */
    protected function __construct($mass, $radius)
    {
        $this->mass = $mass;
        $this->radius = $radius;
    }

    /**
     * @return float
     */
    public function mass()
    {
        return $this->mass;
    }

    /**
     * @return float
     */
    public function radius()
    {
        return $this->radius;
    }

    /**
     * @return float
     */
    public function surfaceGravity()
    {
        return self::$G * $this->mass / ($this->radius * $this->radius);
    }

    /**
     * @param float $otherMass
     * @return float
     */
    public function surfaceWeight($otherMass)
    {
        return $otherMass * $this->surfaceGravity();
    }
}

$myMass = 80;

foreach (Planet::cases() as $planet) {
    printf("Your weight on %s is %f\n", $planet, $planet->surfaceWeight($myMass));
}

如何运行测试

安装依赖项

docker run -v `pwd`:/var/www --rm feitosa/php55-with-composer composer install

运行测试

docker run -v `pwd`:/var/www --rm feitosa/php55-with-composer vendor/bin/phpunit