PHP 枚举类型的管理与设计知识点总结


Posted in PHP onFebruary 13, 2020

今天来分享下如何管理 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 作为一门弱类型语言,参数限定的不足会导致很多不可预期的错误发生,通过使用枚举类,我们进一步加强了参数限定的功能,同时,管理枚举类型也更加的方便统一。

以上就是本次介绍的全部相关知识点,感谢大家的学习和对三水点靠木的支持。

PHP 相关文章推荐
php使用curl检测网页是否被百度收录的示例分享
Jan 31 PHP
PHP获取浏览器信息类和客户端地理位置的2个方法
Apr 24 PHP
PDO预处理语句PDOStatement对象使用总结
Nov 20 PHP
php延迟静态绑定实例分析
Feb 08 PHP
php从完整文件路径中分离文件目录和文件名的方法
Mar 13 PHP
php字符串函数学习之strstr()
Mar 27 PHP
PHP中的事务使用实例
May 26 PHP
PHP实现简单实用的验证码类
Jul 29 PHP
Laravel实现表单提交
May 07 PHP
PHP get_html_translation_table()函数用法讲解
Feb 16 PHP
PHP中迭代器的简单实现及Yii框架中的迭代器实现方法示例
Apr 26 PHP
php 防护xss,PHP的防御XSS注入的终极解决方案
Apr 01 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
Feb 12 #PHP
分享8个Laravel模型时间戳使用技巧小结
Feb 12 #PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
Feb 11 #PHP
thinkphp5框架路由原理与用法详解
Feb 11 #PHP
php数组指针函数功能及用法示例
Feb 11 #PHP
PHP实现单例模式建立数据库连接的方法分析
Feb 11 #PHP
php-7.3.6 编译安装过程
Feb 11 #PHP
You might like
解析php dirname()与__FILE__常量的应用
2013/06/24 PHP
php自动加载autoload机制示例分享
2014/02/20 PHP
Smarty实现页面静态化(生成HTML)的方法
2016/05/23 PHP
ThinkPHP框架整合微信支付之JSAPI模式图文详解
2019/04/09 PHP
JavaScript 对象链式操作测试代码
2010/04/25 Javascript
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
jquery animate图片模向滑动示例代码
2011/01/26 Javascript
JavaScript DOM 编程艺术(第2版)读书笔记(JavaScript的最佳实践)
2013/10/01 Javascript
js实现tab切换效果实例
2015/09/16 Javascript
javascript实现禁止复制网页内容汇总
2015/12/30 Javascript
JavaScript中的对象和原型(一)
2016/08/12 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
JS动态修改网页body的背景色实例代码
2017/10/07 Javascript
VUE 配置vue-devtools调试工具及安装方法
2018/09/30 Javascript
[49:21]TNC vs VG 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第三场 8.20.mp4
2019/08/22 DOTA
Python实现文件信息进行合并实例代码
2018/01/17 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
解决pycharm界面不能显示中文的问题
2018/05/23 Python
python使用wxpy实现微信消息防撤回脚本
2019/04/29 Python
新手常见Python错误及异常解决处理方案
2020/06/18 Python
详解Python多线程下的list
2020/07/03 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
巧用HTML5给按钮背景设计不同的动画简单实例
2016/08/09 HTML / CSS
美国大型的健身社区和补充商店:Bodybuilding.com
2016/09/06 全球购物
俄罗斯护发和专业化妆品购物网站:Hihair
2019/09/28 全球购物
RealTek面试题
2016/06/28 面试题
创业计划书如何编写
2014/02/06 职场文书
网管求职信
2014/03/03 职场文书
创建卫生先进单位实施方案
2014/03/10 职场文书
建设单位项目负责人任命书
2014/06/06 职场文书
井冈山红色之旅感想
2014/10/07 职场文书
2014年党委工作总结
2014/11/22 职场文书
告知书格式
2015/07/01 职场文书
2016年基层党组织公开承诺书
2016/03/25 职场文书
python playwright之元素定位示例详解
2022/07/23 Python