了解Java的Php程序员都知道,PHP一直以来是没有Enum这个特性的,虽然有一个扩展的类可以实现类似的功能,但总感觉不是“原生”,刚好现在需要用到PHP8.1版本,这里记录一下对PHP的枚举Enum的简单使用。
1、先定义一个枚举Trait,因为PHP的枚举不能扩展。
<?php
namespace App\Traits;
trait EnumExtend
{
// 以array返回枚举的key
public static function keys(): array
{
return array_map(function ($item) {
return $item->name;
}, self::cases());
}
// 以['key' => 'value', ...]形式返回枚举内容,可供select组件选择使用
public static function keyValues(): array
{
$result = [];
foreach (self::cases() as $item) {
$result[$item->name] = $item->value;
}
return $result;
}
// 判断持久层返回的是否相同
public function equal(string $value): bool
{
return self::tryFrom($value) === $this;
}
// 判断string key是否包含在枚举里面
public static function include(string $value): bool
{
return in_array($value, self::keys());
}
// 判读多个string key是否全部包含在枚举里面
public static function includeAll(array $names): bool
{
$keys = self::keys();
foreach ($names as $name) {
if (!in_array($name, $keys)) {
return false;
}
}
return true;
}
}
2、定义枚举
<?php declare(strict_types=1);
namespace App\Enums;
use App\Traits\EnumExtend;
/**
* 商品类型
*/
enum ProductType: string
{
use EnumExtend;
case PRODUCT = '商品';
case SERVICE = '服务';
case CONSUMPTION = '消耗品';
}
3、具体应用
<?php
// 列表枚举的 key
ProductType::keys();
// output: ['PRODUCT', 'SERVICE', 'CONSUMPTION']
// 列出枚举的key => value
ProductType::keyValues();
// output: ['PRODUCT' => '商品', 'SERVICE' => '服务', 'CONSUMPTION' => '消耗品']
// 这里我用于前端Select组件选择,保存key值在数据库中,如:ProductModel.product_type = 'PRODUCT'
// 在前端列表等显示界面,通过product_type = 'PRODUCT'显示出“商品”
// 简单判断类型
if (ProductType::PRODUCT->equal(ProductModel.product_type)) {
// ...
} else if (ProductType::SERVICE->equal(ProductModel.product_type)) {
// ...
} else {}
// 判断是否包含key,如:前端输入的值是否合法
$formData = ['product_type' => 'PRODUCT'];
ProductType::include($formData['product_type']);
// output: true
// 判断是否包含多个key,如:前端输入的多个值是否合法
$formData = ['product_type' => ['PRODUCT', 'PRODUCT2']];
ProductType::includeAll($formData['product_type']);
// output: false
4、其它应用
前端的使用基本满足简单应用的情况了。如果还有更复杂的,可以深入了解。
例如使用PHP的注解结合枚举使用:
4.1、定义注解
<?php
namespace App\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Description
{
private $value;
public function __construct($value = ''){
$this->value = $value;
}
}
4.2、在枚举中使用
<?php declare(strict_types=1);
namespace App\Enums;
use App\Traits\EnumExtend;
use App\Attributes\Description;
/**
* 商品类型
*/
enum ProductType: int
{
use EnumExtend;
#[Description('商品')]
case PRODUCT = 1;
#[Description('服务')]
case SERVICE = 2;
#[Description('消耗品')]
case CONSUMPTION = 3;
public function getDescription() {
$ref = new \ReflectionEnumUnitCase(self::class, $this->name);
$attributes = $ref->getAttributes();
foreach ($attributes as $attribute) {
$args = $attribute->getArguments();
return $args[0];
}
return '';
}
public static function keyValues(): array
{
$result = [];
foreach (self::cases() as $item) {
$result[$item->value] = $item->getDescription();
}
return $result;
}
}
ProductType::PRODUCT->name; // PRODUCT
ProductType::PRODUCT->value; // 1
ProductType::PRODUCT->getDescription(); // 商品
ProductType::keyValues(); // [1 => '商品', 2 => '服务', 3 => '消耗品']