PHP中实现多值枚举

PHP 枚举

前面的文章中咱们介绍了PHP枚举的使用,最近对项目总体进行重构,增长了枚举类的封闭性和安全性,尤为对多值枚举进行了优化。php

枚举类

PHPEnum包含三个核心枚举类,分别为:前端

  • 基础枚举 - 测试用例 这是一个单值枚举类,也是一个基础类,枚举类都会继承此类
  • 列表枚举 - 测试用例 这是一个基于单值枚举类实现的多值枚举类,能够定义任意数量的属性
  • 数组枚举 - 测试用例 这是一个多值枚举的实现类,基于最经常使用的两个属性值的枚举场景预约义了key和value两个属性

这里所说的单值和多值的值是指属性值,其实枚举自己没有单值和多值之分,但因为语言特性,没有很好的办法将其在一个类中实现。git

快速开始

让咱们经过一个表示用户性别的枚举为例,来了解各个枚举的用法和区别github

数组枚举

定义数组枚举时须要注意全部的常量值都须要定义为有两个元素的数组,不然系统将会抛出一个异常数组

首先咱们基于数组枚举来定义用户性别枚举,它的定义方式与普通的常量定义同样:缓存

class UserGenderEnum extends \PhpEnum\ArrayEnum { 
    const MALE   = [1, 'male'];
    const FEMALE = [2, 'female']; 
 }

当咱们定义好用户性别枚举后,让咱们看看数组枚举为咱们提供了哪些功能:安全

  1. 当咱们想获取一个男性的枚举实例时,咱们能够经过下面任意一个方法,获取到的枚举实例始终为同一个测试

    UserGenderEnum::MALE() // 只会缓存当前实例
       UserGenderEnum::ofEnumName('MALE') // 会缓存全部实例       
       UserGenderEnum::ofKey(1) // 会缓存全部实例
       UserGenderEnum::ofValue('male') // 会缓存全部实例
  2. 当咱们想获取枚举名称或属性值时,咱们能够这样作优化

    UserGenderEnum::MALE()->name() // string(4) "MALE" 
        UserGenderEnum::MALE()->getKey() // int(1) 
        UserGenderEnum::MALE()->getValue() // string(4) "male"
  3. 当咱们想比较一个属性时,咱们能够这样作this

    UserGenderEnum::MALE()->enumNameEquals('MALE') // bool(true)
        UserGenderEnum::MALE()->keyEquals(1) // bool(true)
        UserGenderEnum::MALE()->valueEquals('male') // bool(true)
  4. 当咱们想要验证前端传递的数据是否正确时,枚举能够很快速的实现它

    UserGenderEnum::containsEnumName('MALE') // int(1) 返回查找到的枚举数量
       UserGenderEnum::containsKey(1) // int(1) 返回查找到的枚举数量 
       UserGenderEnum::containsValue('male') // int(1) 返回查找到的枚举数量
  5. 可能有的时候咱们没法获得一个具体的值去验证,好比在Laravel验证器中,咱们须要获得一个字符串进行验证,只须要这么作

    implode(',', UserGenderEnum::names()) // string(11) "MALE,FEMALE"
        implode(',', UserGenderEnum::getProperties('key')) // string(3) "1,2"
        implode(',', UserGenderEnum::getProperties('value')) // string(11) "male,female"

经过上面的示例咱们了解到了数组枚举部分功能的用法,但你可能以为预约义的属性名称key和value
在不一样的场景下对理解它们表明什么含义并不友好,那么接下来你须要了解下列表枚举的使用。

列表枚举

定义列表枚举时须要注意必需要定义protected修饰的构造方法listEnumConstruct,枚举常量值必须为非空数组且长度要与构造方法参数的个数彻底一致,不然系统将会抛出一个异常

此次让咱们基于列表枚举来定义用户性别枚举, 此次除了定义常量外,咱们使用了自定义的属性名称id和name,并经过构造方法为其赋值

class UserGenderEnum extends \PhpEnum\ListEnum {
 
     const MALE   = [1, 'male'];
     const FEMALE = [2, 'female'];
     
     private $id;
     private $name;
     
     protected function listEnumConstruct($id, $name)
     { 
         $this->id = $id;
         $this->name = $name; 
     } 
 }

当咱们定义好用户性别枚举后,上面咱们在数组枚举中演示过的功能在这里也全都生效,只是须要将key换成id,将value换成name,如:

  1. 当咱们想获取一个男性的枚举实例时,咱们能够经过下面任意一个方法,获取到的枚举实例始终为同一个。

    UserGenderEnum::MALE() // 只会缓存当前实例
        UserGenderEnum::ofEnumName('MALE') // 会缓存全部实例
        UserGenderEnum::ofId(1) // 会缓存全部实例
        UserGenderEnum::ofName('male') // 会缓存全部实例
  2. 当咱们想获取枚举名称或属性值时,咱们能够这样作

    UserGenderEnum::MALE()->name() // string(4) "MALE"
        UserGenderEnum::MALE()->getId() // int(1)
        UserGenderEnum::MALE()->getName() // string(4) "male"
  3. 当咱们想比较一个属性时,咱们能够这样作

    UserGenderEnum::MALE()->enumNameEquals('MALE') // bool(true)
        UserGenderEnum::MALE()->idEquals(1) // bool(true)
        UserGenderEnum::MALE()->nameEquals('male') // bool(true)
  4. 当咱们想要验证前端传递的数据是否正确时,枚举能够很快速的实现它

    UserGenderEnum::containsEnumName('MALE') // int(1) 返回查找到的枚举数量
        UserGenderEnum::containsId(1) // int(1) 返回查找到的枚举数量
        UserGenderEnum::containsName('male') // int(1) 返回查找到的枚举数量
  5. 可能有的时候咱们没法获得一个具体的值去验证,好比在Laravel验证器中,咱们须要获得一个字符串进行验证,只须要这么作

    implode(',', UserGenderEnum::names()) // string(11) "MALE,FEMALE" 
        implode(',', UserGenderEnum::getProperties('id')) // string(3) "1,2"
        implode(',', UserGenderEnum::getProperties('name')) // string(11) "male,female"

列表枚举的实现可能是参考JAVA枚举,但因为JAVA自己是在语言层面对枚举功能作的支持,定义JAVA枚举元素就是在定义构造方法,这些在PHP中没法支持,因此只能用数组来代替。

基础枚举

基础枚举是单值枚举,只有属性名称name和属性值value,基础枚举不限制属性值的类型,但同时属性值始终做为一个总体,没法再细分

此次让咱们再基于基础枚举来定义用户性别枚举,基础枚举的定义同数组枚举的定义相同

class UserGenderEnum extends \PhpEnum\Enum { 
    const MALE   = [1, 'male'];
    const FEMALE = [2, 'female']; 
 }

当咱们定义好用户性别枚举后,让咱们看看基础枚举为咱们提供了哪些功能(注意基础枚举中的属性值[1, 'male']只能做为一个总体使用):

  1. 当咱们想获取一个男性的枚举实例时,咱们能够经过下面任意一个方法,获取到的枚举实例始终为同一个

    UserGenderEnum::MALE() // 只会缓存当前实例
        UserGenderEnum::ofEnumName('MALE') // 会缓存全部实例
        UserGenderEnum::ofEnumValue([1, 'male']) // 会缓存全部实例
  2. 当咱们想获取枚举名称或属性值时,咱们能够这样作

    UserGenderEnum::MALE()->name() // string(4) "MALE"
        UserGenderEnum::MALE()->value() // array(2) {[0]=>int(1)[1]=>string(4) "male"}
  3. 当咱们想比较一个属性时,咱们能够这样作

    UserGenderEnum::MALE()->enumNameEquals('MALE') // bool(true) 
        UserGenderEnum::MALE()->enumValueEquals([1, 'male']) // bool(true)
  4. 当咱们想要验证前端传递的数据是否正确时,枚举能够很快速的实现它

    UserGenderEnum::containsEnumName('MALE') // int(1) 返回查找到的枚举数量 
        UserGenderEnum::containsValue([1, 'male']') // int(1) 返回查找到的枚举数量
  5. 当咱们须要获得一个字符串时,能够这样作

    implode(',', UserGenderEnum::names()) // string(11) "MALE,FEMALE"

到这里枚举经常使用的功能就介绍完了,三种不一样类型的枚举提供不一样的功能,要根据实际的使用场景进行选择使用

相关文章
相关标签/搜索