枚举以各种不同功能的形式出现在诸多语言中。 在 PHP 中, 枚举是一种特殊类型的对象。Enum 本身是一个类(Class), 它的各种条目(case)是这个类的单例对象,意味着也是个有效对象 —— 包括类型的检测,能用对象的地方,也可以用它。
最常见的枚举例子是内置的 boolean 类型, 该枚举类型有两个有效值 true 和 false。 Enum 使开发者能够任意定义出用户自己的、足够健壮的枚举。
今个做个示例 用注释的方式来实现对PHP枚举的增强, 引入扩展 MyCLabs\Enum
composer require myclabs/php-enum
下面直接上示例使用效果:
var_dump(UseCode::BXFY_CHAILVFEI);
//输出 int(311)
//数据库取出后常用到输入标签
$n = 312;
var_dump(UseCode::label($n));
//输出 string(23) "报销费用--办公费"
//查询时查用到条件选择
var_dump(UseCode::options());
//输出
array(4) {
["BXFY_CHAILVFEI"]=>
array(2) {
["tit"]=>
string(23) "报销费用--差旅费"
["val"]=>
int(311)
}
["BXFY_BANGONGFEI"]=>
array(2) {
["tit"]=>
string(23) "报销费用--办公费"
["val"]=>
int(312)
}
["BXFY_SHUIDIANFEI"]=>
array(2) {
["tit"]=>
string(23) "报销费用--水电费"
["val"]=>
int(313)
}
["BXFY_TONGXUNFEI"]=>
array(2) {
["tit"]=>
string(23) "报销费用--通讯费"
["val"]=>
int(314)
}
}
使用了ReflectionClass 对类进行扫描注释,
1、根据Enum常量注释获取label说明
2、获取Enum所有常量数组,返回:[ 常量名=>['tit'=>常量说明, 'val'=>常量值] ]
直接上实际代码示例:
主要Enum基类 BasicEnum 和 示例类 UseCode
BasicEnum.php代码如下:
//注意自己的包名
<?php
namespace cmbc\Enums;
use MyCLabs\Enum\Enum;
use ReflectionClass;
/**
* Enum主类
* 代码中的 'tit'、'val'自定义的Key名称,可自行修改
*/
class BasicEnum extends Enum
{
/**
* 根据Enum常量注释获取label说明, TODO:提高效率:做好缓存
* @param $val
* @return string
*/
public static function label($val): string
{
$arr = self::options();
foreach ($arr as $key=>$v){
if($v['val']==$val) return $v['tit'];
}
return $val;
}
/**
* 获取Enum所有常量数组,返回:[ 常量名=>['tit'=>常量说明, 'val'=>常量值] ]
* @return array
*/
public static function options(): array
{
$array = [];
$class = new ReflectionClass(get_called_class());
$constants = $class->getConstants();
foreach ($constants as $constantName => $constantValue) {
$comment = $class->getReflectionConstant($constantName)->getDocComment();
//这里可扩展, 只对常用的值做替换
$title = trim(preg_replace('/^\/\*\*.*?@var.*[int|string|bool](.*?)\*\/$/', '$1', $comment));
$array[$constantName] = ['tit'=>$title, 'val'=>$constantValue];
}
return $array;
}
}
示例类 UseCode.php代码如下:
<?php
//注意自己的包名
namespace cmbc\Enums;
/**
* 常用用途代码及其含义
*
*/
final class UseCode extends BasicEnum
{
//常量的定义
// /** @var int 常量注释用于文字说明 label 标签 */
// const 常量名称 = 常量值;
/** @var int 报销费用--差旅费 */
const BXFY_CHAILVFEI = 311;
/** @var int 报销费用--办公费 */
const BXFY_BANGONGFEI = 312;
/** @var int 报销费用--水电费 */
const BXFY_SHUIDIANFEI = 313;
/** @var int 报销费用--通讯费 */
const BXFY_TONGXUNFEI = 314;
}
还有其他更好的方式, 还请评论中 多指教!