Skip to content
yinfuyuan edited this page Dec 24, 2020 · 9 revisions

PHP 枚举

PHPEnum是为PHP开发人员准备的枚举类库。其想法来源于 Java枚举 并利用PHP的特性巧妙的实现单值枚举和多值枚举。PHPEnum与Laravel集成非常方便。

版本

依赖 PHP version 8.*

从 Version-3.0 起在 Version-1.3 的基础上在主分支进行新功能开发 3.x

此版本支持PHP8 会引入强类型约束增强枚举的安全性

依赖 PHP version 7.*

从 Version-2.0 起在 Version-1.3 的基础上独立出一个新的分支 2.x 以保持对 PHP version 7.* 的支持

此版本使用PHP7的语法,部分新功能会在此版本上进行开发

依赖 PHP version 5.6+

从 Version-1.3 开始从主分支上独立出一个分支 1.x 以保持对 PHP version 5.6+ 的支持

从 Version-1.3 开始在 Version-1.2 的基础上进行了重构,真正在PHP version 5.6 环境上开发的

实现的功能大体没变,增加了枚举类的封闭性和安全性,增强了列表枚举的实现,也对大量的方法进行重新命名

依赖 PHP version 5.6+

这个版本比较特殊,由于是在 PHP version 7.0 上开发的,导致有少部分语法是 PHP version 7.0 的,在 PHP version 5.6 并不能运行。 这个版本不在维护,并会在未来的计划中废弃,请尽快升级到 Version-1.3 及以上版本。 在这个版本中,列表枚举功能并不完善,这也是 数组枚举 产生的原因

枚举类

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

  • 基础枚举 - 测试用例 这是一个单值枚举类,也是一个基础类,枚举类都会集成此类
  • 列表枚举 - 测试用例 这是一个基于单值枚举类实现的多值枚举类,可以定义任意数量的属性
  • 数组枚举 - 测试用例 这是一个基于多值枚举实现的两值枚举类,也是列表枚举的快速实现,内置了key和value两个属性

这里所说的单值和多值的值是指属性值,其实枚举本身没有单值和多值之分,但在PHP的枚举实现中,大多是没有属性这个概念的,所以在这里进行了区分。

快速开始

首先让我们定义一个用户性别的枚举,它的定义方式与普通常量并没有什么区别:

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

当我们定义好枚举后,让我们看看数组枚举为我们提供了哪些功能:

当我们想获取一个男性的枚举实例时,我们可以通过下面任意一个方法,获取到的枚举实例始终为同一个。

UserGenderEnum::MALE() // 只会缓存当前实例
UserGenderEnum::ofEnumName('MALE') // 会缓存所有实例
UserGenderEnum::ofKey(1) // 会缓存所有实例
UserGenderEnum::ofValue('male') // 会缓存所有实例

当我们想获取枚举名称或属性值时,我们可以这样做

UserGenderEnum::MALE()->name() // string(4) "MALE"
UserGenderEnum::MALE()->getKey() // int(1)
UserGenderEnum::MALE()->getValue() // string(4) "male"

当我们想比较一个属性时,我们可以这样做

UserGenderEnum::MALE()->enumNameEquals('MALE') // bool(true)
UserGenderEnum::MALE()->keyEquals(1) // bool(true)
UserGenderEnum::MALE()->valueEquals('male') // bool(true)

当我们想要验证前端传递的数据是否正确时,枚举可以很快速的实现它

UserGenderEnum::containsEnumName('MALE') // bool(true)
UserGenderEnum::containsKey(1) // bool(true)
UserGenderEnum::containsValue('male') // bool(true)

可能有的时候我们无法得到一个具体的值去验证,比如在Laravel验证器中,我们需要得到一个字符串进行验证

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

通过上面的示例我们可以了解到了枚举的强大,不管是横向的数据还是纵向数据,不管是单个属性还是全部数据,我们都可以轻松读取 但是你可能会有疑问,这些方法中出现的key和value是什么,我可以自己定义吗,我可以定义单个或多个属性值吗? 答案是完全可以

上面的枚举是以数组枚举为基类,当需要自定义属性时,应该以列表枚举为基类,下面我们来重新定义用户性别枚举

class UserGenderEnum extends \PhpEnum\ListEnum
{
    const MALE   = [1, 'male', 'man'];
    const FEMALE = [2, 'female', 'woman'];

    private $id;
    private $name;
    private $alias;

    protected function listEnumConstruct($id = null, $name = null, $alias = null)
    {
        $this->id = $id;
        $this->name = $name;
        $this->alias = $alias;
    }
}

这次我们定义常量数组时多加了一个数组元素,之后我们为每个元素都定义了一个属性作为载体并在构造方法中为其赋值 除此之外我们无需再进行其他的定义,就可以直接使用上面示例给到的所有方法,如:

当我们想获取一个男性的枚举实例时,我们可以通过下面任意一个方法,获取到的枚举实例始终为同一个。

UserGenderEnum::MALE() // 只会缓存当前实例
UserGenderEnum::ofEnumName('MALE') // 会缓存所有实例
UserGenderEnum::ofId(1) // 会缓存所有实例
UserGenderEnum::ofName('male') // 会缓存所有实例
UserGenderEnum::ofAlias('man') // 会缓存所有实例

当我们想获取枚举名称或属性值时,我们可以这样做

UserGenderEnum::MALE()->name() // string(4) "MALE"
UserGenderEnum::MALE()->getId() // int(1)
UserGenderEnum::MALE()->getName() // string(4) "male"
UserGenderEnum::MALE()->getAlias() // string(3) "man"

其他的方法就不一一列举了,赶快下载进行体验吧!

Clone this wiki locally