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 addslashes和mysql_real_escape_string
Jan 24 PHP
PHP 文件缓存的性能测试
Apr 25 PHP
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
May 07 PHP
关于访问控制的一首PHP面试题(对属性或方法的访问控制)
Sep 13 PHP
php对大文件进行读取操作的实现代码
Jan 23 PHP
PHP数字和字符串ID互转函数(类似优酷ID)
Jun 30 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
php上传图片获取路径及给表单字段赋值的方法
Jan 23 PHP
PHP请求Socket接口测试实例
Aug 12 PHP
Yii2框架中使用PHPExcel导出Excel文件的示例
Aug 09 PHP
PHP基于PDO扩展操作mysql数据库示例
Dec 24 PHP
Laravel5.4框架中视图共享数据的方法详解
Sep 05 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的优缺点
2015/07/14 PHP
php安装ssh2扩展的方法【Linux平台】
2016/07/20 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
PHP模版引擎原理、定义与用法实例
2019/03/29 PHP
PHP的imageTtfText()函数深入详解
2021/03/03 PHP
jquery ajax结合thinkphp的getjson实现跨域的方法
2016/06/06 Javascript
谈谈target=_new和_blank的不同之处
2016/10/25 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
2017/02/22 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
2018/09/26 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
Vue.js中provide/inject实现响应式数据更新的方法示例
2019/10/16 Javascript
JS实现随机点名器
2020/04/12 Javascript
微信小程序实现点赞业务
2021/02/10 Javascript
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
Python中使用支持向量机SVM实践
2017/12/27 Python
Python实现OpenCV的安装与使用示例
2018/03/30 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
2020/07/03 Python
OpenCV读取与写入图片的实现
2020/10/13 Python
python实现计算图形面积
2021/02/22 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
科尔士百货公司官网:Kohl’s
2016/07/11 全球购物
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
Maje德国官网:法国女性成衣品牌
2017/02/10 全球购物
英国历史最悠久的DJ设备供应商:DJ Finance、DJ Warehouse、The DJ Shop
2019/09/04 全球购物
成人高等教育毕业生自我鉴定
2013/10/22 职场文书
总账会计岗位职责
2014/03/13 职场文书
活动策划求职信模板
2014/04/21 职场文书
校园环保广播稿(3篇)
2014/09/15 职场文书
在宿舍喝酒的检讨书
2014/09/28 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
交通事故起诉书
2015/05/19 职场文书
小学班主任教育随笔
2015/08/15 职场文书
导游词之烟台威海蓬莱
2019/11/14 职场文书
Vue通过懒加载提升页面响应速度
2021/05/10 Vue.js
PHP实现rar解压读取扩展包小结
2021/06/03 PHP