PHP上的枚举

我知道PHP还没有本机枚举。但是我已经从Java世界习惯了它们。我希望使用枚举作为一种方式来提供预定义的值,IDE的自动完成功能可以理解这些值

常量可以做到这一点,但存在名称空间冲突问题(或者实际上是因为它们是全局的)。数组没有名称空间问题,但它们太模糊,在运行时会被覆盖,IDE很少知道如何在没有额外静态分析注释或属性的情况下自动填充它们的键

您是否有常用的解决方案/变通方法?有人记得PHP的人是否有过关于枚举的想法或决定吗

根据用例的不同,我通常会使用一些简单的,如下所示:

抽象类DaysOfWeek
{
const Sunday=0;
常数星期一=1;
//等等。
}
$today=DaysOfWeek::Sunday;

然而,其他用例可能需要对常量和值进行更多的验证。根据以下关于反思的评论和其他一些注释,这里有一个扩展的示例,它可能更好地服务于更广泛的案例:

抽象类BasicEnum{
私有静态$constCacheArray=NULL;
私有静态函数getConstants(){
if(self::$constCacheArray==NULL){
self::$constCacheArray=[];
}
$calledClass=get_called_class();
如果(!array_key_)存在($calledClass,self:$constCacheArray)){
$reflect=新的ReflectionClass($calledClass);
self::$constCacheArray[$calledClass]=$reflect->getConstants();
}
返回self::$constCacheArray[$calledClass];
}
公共静态函数isValidName($name,$strict=false){
$constants=self::getConstants();
如果($严格){
返回数组\键\存在($name,$constants);
}
$keys=数组_映射('strtolower',数组_键($constants));
返回数组(strtolower($name),$keys);
}
公共静态函数isValidValue($value,$strict=true){
$values=数组_值(self::getConstants());
返回数组($value,$values,$strict);
}
}

通过创建扩展BasicEnum的简单枚举类,您现在可以使用方法进行简单的输入验证:

抽象类DaysOfWeek扩展了BasicEnum{
const Sunday=0;
常数星期一=1;
const周二=2;
常数星期三=3;
常数星期四=4;
常数星期五=5;
康斯特星期六=6;
}
DaysOfWeek::isValidName('Humpday');//错误的
DaysOfWeek::isValidName(“星期一”);//符合事实的
DaysOfWeek::isValidName(“星期一”);//符合事实的
DaysOfWeek::isValidName('monday',$strict=true);//错误的
DaysOfWeek::isValidName(0);//错误的
DaysOfWeek::isValidValue(0);//符合事实的
DaysOfWeek::isValidValue(5);//符合事实的
DaysOfWeek::isValidValue(7);//错误的
DaysOfWeek::isValidValue('Friday');//错误的

作为旁注,每当我在数据不会更改的静态/常量类(例如在枚举中)上至少使用一次反射时,我都会缓存这些反射调用的结果,因为每次使用新的反射对象最终都会产生显著的性能影响(存储在多个枚举的关联数组中)

现在,大多数人已经最终升级到至少5.3,并且SplEnum可用,这当然也是一个可行的选择——只要您不介意在整个代码库中使用实际枚举实例化的传统非直观概念。在上面的示例中,BasicEnumDaysOfWeek根本不能实例化,也不应该实例化

发表评论