PHP 枚举类型的管理与设计
发布:smiling 来源: PHP粉丝网 添加日期:2022-06-03 08:32:04 浏览: 评论:0
本文的实现主要是基于 myclabs/php-enum 扩展包。
今天来分享下如何管理 PHP 的枚举类型。
一种常见的方式是,使用常量来代表枚举类型
const YES = '是';
const NO = '否';
可以在这个基础上更进一步,将其封装成类,以便于管理。
- class BoolEnum {
- const YES = '是';
- const NO = '否';
- }
现在,我们希望能通过方法来动态调用对应的枚举类型
BoolEnum::YES(); // 是
BoolEnum::NO(); // 否
也可以批量获取枚举类型
BoolEnum::toArray(); // ['Yes' => '是', 'No' => '否']
下面来实现上面列举的功能。
定义基本的枚举基类,让所有的枚举类都继承该抽象基类。
- abstract class Enum
- {
- // 获取所有枚举类型
- public static function toArray(){
- // 通过反射获取常量
- $reflection = new \ReflectionClass(static::class);
- $contants = $reflection->getConstants();
- // 返回对应的常量
- return $contants;
- }
- // 动态调用属性
- public static function __callStatic($name, $arguments)
- {
- $arr = static::toArray();
- if(isset($arr[$name])){
- return $arr[$name];
- }
- throw new \BadMethodCallException("找不到对应的枚举值 {$name}");
- }
- }
- class BoolEnum extends Enum
- {
- const YES = '是';
- const NO = '否';
- }
利用反射,可以获取到所有的枚举类型。同时,利用魔术方法则可以实现对属性的动态调用,这里要注意的是,反射会消耗较多的资源,因此,对 toArray 方法进行重构,增加一个缓存变量来缓存获取到的枚举类型,避免重复使用反射。
- abstract class Enum
- {
- protected static $cache = [];
- public static function toArray(){
- $class = static::class;
- // 第一次获取,就通过反射来获取
- if(! isset(static::$cache[$class])){
- $reflection = new \ReflectionClass(static::class);
- static::$cache[$class] = $reflection->getConstants();
- }
- return static::$cache[$class];
- }
- }
现在考虑更多的使用场景,比如用实例来代表特定枚举类型
$yes = new BoolEnum("是");
echo $yes; // "是"
实现如下:
- abstract Enum
- {
- protected $value;
- public function __construct($value)
- {
- if ($value instanceof static) {
- $value = $value->getValue();
- }
- if(! $this->isValid($value)){
- throw new \UnexpectedValueException("$value 不属于该枚举值" . static::class);
- }
- $this->value = $value;
- }
- // 获取实例对应的键
- public function getKey(){
- return array_search($this->value, static::toArray(), true);
- }
- // 获取实例对应的值
- public function getValue()
- {
- return $this->value;
- }
- // 允许字符串形式输出
- public function __toString()
- {
- return $this->value;
- }
- // 验证值是否合法
- public function isValid($value)
- {
- $arr = static::toArray();
- return in_array($value, $arr, true);
- }
- // 验证键是否合法
- public function isValidKey($key)
- {
- $arr = static::toArray();
- return array_key_exists($key, $arr);
- }
- }
这样做可避免用户使用非法的枚举类型的值
- $user->banned = '非法值'; // 可能不会报错
- $yes = new BoolEnum("非法值"); // 将会抛出异常
- $user->banned = $yes;
或者作为参数类型限定
- function setUserStatus(BoolEnum $boolEnum){
- $user->banned = $boolEnum;
- }
PHP 作为一门弱类型语言,参数限定的不足会导致很多不可预期的错误发生,通过使用枚举类,我们进一步加强了参数限定的功能,同时,管理枚举类型也更加的方便统一。
Tags: PHP枚举类型
- 上一篇:PHP基于ElasticSearch做搜索
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)