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 相关文章推荐
怎么使 Mysql 数据同步
Oct 09 PHP
PHP 面向对象 final类与final方法
May 05 PHP
PHP 事务处理数据实现代码
May 13 PHP
使用php发送有附件的电子邮件-(PHPMailer使用的实例分析)
Apr 26 PHP
解析PHP计算页面执行时间的实现代码
Jun 18 PHP
PHP安装memcached扩展笔记
May 28 PHP
php使用CutyCapt实现网页截图保存的方法
Oct 03 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
Jun 20 PHP
Yii框架页面渲染操作实例详解
Jul 19 PHP
PHP使用openssl扩展实现加解密方法示例
Feb 20 PHP
Laravel 5+ .env环境配置文件详解
Apr 06 PHP
PHP tp5中使用原生sql查询代码实例
Oct 28 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
MyEclipse常用配置图文教程
2014/09/11 PHP
php 解析xml 的四种方法详细介绍
2016/10/26 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
2017/11/10 PHP
PHP实现提取多维数组指定一列的方法总结
2019/12/04 PHP
Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
2010/06/11 Javascript
用jquery方法操作radio使其默认选项是否
2013/09/10 Javascript
jQuery实现防止提交按钮被双击的方法
2015/03/24 Javascript
在Python中使用glob模块查找文件路径的方法
2015/06/17 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
2016/02/15 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
vue实现全选和反选功能
2017/08/31 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
Vue运用transition实现过渡动画
2019/05/06 Javascript
JQuery中DOM节点的操作与访问方法实例分析
2019/12/23 jQuery
javascrpt密码强度校验函数详解
2020/03/18 Javascript
vue项目中js-cookie的使用存储token操作
2020/11/13 Javascript
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python使用Turtle库绘制动态钟表
2018/11/19 Python
图解python全局变量与局部变量相关知识
2019/11/02 Python
Django 限制访问频率的思路详解
2019/12/24 Python
appium+python adb常用命令分享
2020/03/06 Python
tensorflow转换ckpt为savermodel模型的实现
2020/05/25 Python
基于python模拟bfs和dfs代码实例
2020/11/19 Python
python tqdm库的使用
2020/11/30 Python
英国知名奢侈品包包品牌:Milli Millu
2016/12/22 全球购物
美国沙龙美发产品购物网站:Hair.com by L’Oreal
2020/11/09 全球购物
PHP如何去执行一个SQL语句
2016/03/05 面试题
掌上明珠Java程序员面试总结
2016/02/23 面试题
商场端午节活动方案
2014/01/29 职场文书
三项教育活动实施方案
2014/03/30 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
感谢信怎么写
2015/01/21 职场文书
2015年母亲节寄语
2015/03/23 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis