在 PHP 7 中,创建类似枚举的行为的推荐方法是什么?

15 浏览
0 Comments

在 PHP 7 中,创建类似枚举的行为的推荐方法是什么?

该问题已经有了答案:PHP中的枚举

有点出乎意料的是,PHP没有原生支持枚举。在PHP 5.4中,可以使用本机扩展SPL_Types来模拟SplEnum的行为,但该扩展的最后更新是在2012年。在PHP 7中,尝试安装该扩展将由于接口更改而引发编译错误。

因此,我想知道目前推荐的获取类似枚举行为的方法是什么。我想能够编写至少类似于以下代码的代码:

enum DaysOfTheWeek
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7
}
$day = DaysOfTheWeek::Monday;
echo $day; //Prints 1

我的当前代码不太简洁,并且具有许多(不必要的)开销:

class DayOfTheWeek
{
    private __value;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
    const Sunday = 7;
    public function __construct(int $value)
    {
        if ($value !== DayOfTheWeek::Monday
            && $value !== DayOfTheWeek::Tuesday
            && $value !== DayOfTheWeek::Wednesday
            && $value !== DayOfTheWeek::Thursday
            && $value !== DayOfTheWeek::Friday
            && $value !== DayOfTheWeek::Saturday
            && $value !== DayOfTheWeek::Sunday
        )
        {
            throw new InvalidArgumentException("Invalid day of the week");
        }
    }
    public function GetValue(): int
    {
        return $this->__value;
    }
}

一些澄清:

为什么不使用抽象类和一些常量值?

因为这完全破坏了PHP 7中的类型提示的想法。我的意思是,我可以告诉一个函数接受这个枚举的一个实例,并确保它是一个合法的值。

为什么不优化一周的天数?你可以通过查看它是否在0到6之间使检查更简单。

因为枚举不必按顺序排列,也不必彼此显示任何关系。枚举可以具有值56、1999、120、-12400、8、-1239和44。枚举的代码不应该依赖于枚举的值。

admin 更改状态以发布 2023年5月23日
0
0 Comments

我喜欢在我的项目中这样做。如果您好奇,您将意识到您可以构建枚举的层次结构,甚至为这些类提供其他用途。

https://gist.github.com/rafageist/aef9825b7c935cdeb0c6187a2d363909

我将此解决方案转换为实际项目。 完整的解决方案在这里:https://github.com/divengine/enum

安装它:

composer require divengine\enum;

定义您的枚举:


使用您的枚举:


0
0 Comments

我仍然会使用一个数组,但是基于ReflectionClass来检查给定的值是否定义在类常量中

getConstants();
        foreach($constants as $dayName=>$dayValue) {
            if($value === $dayValue) {
                $this->__day = $dayName;
                $this->__value = $dayValue;
                break;
            }
        }
        if(is_null($this->__day)) {
            throw new InvalidArgumentException("Invalid day of the week");
        }
    }
    public function GetValue(): int
    {
        return $this->__value;
    }
}

用法:

$return = new DayOfTheWeek(5);
var_dump($return);

输出:

object(DayOfTheWeek)#1 (2) {
  ["__value":"DayOfTheWeek":private]=>
  int(5)
  ["__day":"DayOfTheWeek":private]=>
  string(6) "Friday"
}

我不确定性能问题,但在这里找到了一些信息

更新:阅读文档后,似乎不仅我一个人想到了这个想法......但还是很丑陋......

0