在 PHP 7 中,创建类似枚举的行为的推荐方法是什么?
在 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日
我喜欢在我的项目中这样做。如果您好奇,您将意识到您可以构建枚举的层次结构,甚至为这些类提供其他用途。
https://gist.github.com/rafageist/aef9825b7c935cdeb0c6187a2d363909
我将此解决方案转换为实际项目。 完整的解决方案在这里:https://github.com/divengine/enum。
安装它:
composer require divengine\enum;
定义您的枚举:
使用您的枚举:
我仍然会使用一个数组,但是基于ReflectionClass来检查给定的值是否定义在类常量中
class DayOfTheWeek { private $__value; private $__day; 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) { $myClass = new ReflectionClass ( get_class($this) ); $constants = $myClass->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" }
我不确定性能问题,但在这里找到了一些信息
更新:阅读文档后,似乎不仅我一个人想到了这个想法......但还是很丑陋......