核心库新增EnumTrait

This commit is contained in:
堂吉诃德拉曼查的英豪
2026-08-06 15:28:07 +08:00
parent 2bdfafe32b
commit 454139ac83

126
src/Trait/EnumTrait.php Normal file
View File

@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace Dhd\Micro\Core\Trait;
use InvalidArgumentException;
use ReflectionClass;
/**
* PHP 原生枚举辅助方法(values/descriptions/valueMap/fromValue 等).
*/
trait EnumTrait
{
public static function values(): array
{
self::validateEnumStructure();
$values = [];
foreach (self::cases() as $case) {
$values[] = $case->value;
}
return $values;
}
public static function descriptions(): array
{
self::validateEnumStructure();
$descriptions = [];
foreach (self::cases() as $case) {
$descriptions[] = $case->description();
}
return $descriptions;
}
public static function valueMap(): array
{
self::validateEnumStructure();
$map = [];
foreach (self::cases() as $case) {
$map[$case->value] = $case->description();
}
return $map;
}
public static function fromValue(int|string $value): self
{
self::validateEnumStructure();
$firstCase = self::cases()[0] ?? null;
if ($firstCase) {
$expectedType = gettype($firstCase->value);
$actualType = gettype($value);
if ($expectedType !== $actualType) {
throw new InvalidArgumentException(sprintf(
'枚举值类型不匹配,%s期望%s类型,实际为%s',
self::class,
$expectedType,
$actualType
));
}
}
$enum = self::tryFrom($value);
if (! $enum) {
throw new InvalidArgumentException(sprintf(
'无效的%s值: %s,允许值: %s',
self::class,
$value,
implode(', ', self::values())
));
}
return $enum;
}
public static function fromDescription(string $description): ?self
{
self::validateEnumStructure();
foreach (self::cases() as $case) {
if ($case->description() === $description) {
return $case;
}
}
return null;
}
public static function isValidValue(int|string $value): bool
{
self::validateEnumStructure();
foreach (self::cases() as $case) {
if ($case->value === $value) {
return true;
}
}
return false;
}
private static function validateEnumStructure(): void
{
if (! (new ReflectionClass(self::class))->isEnum()) {
throw new InvalidArgumentException(sprintf(
'EnumTrait仅允许枚举类使用,%s不是枚举',
self::class
));
}
if (! method_exists(self::class, 'description')) {
throw new InvalidArgumentException(sprintf(
'枚举类%s必须实现description()方法(返回字符串描述)',
self::class
));
}
$sampleCase = self::cases()[0] ?? null;
if ($sampleCase && ! is_string($sampleCase->description())) {
throw new InvalidArgumentException(sprintf(
'枚举类%s的description()方法必须返回字符串',
self::class
));
}
}
}