Files
hyperf_data/extend/Aether/PHP/Hyperf/Traits/AetherEnum.php
2025-09-25 09:12:22 +08:00

160 lines
4.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace Aether\Traits;
use App\Notice\Enum\NoticeStatusEnum;
use App\Data\Model\NoticeStatsModel;
use InvalidArgumentException;
use ReflectionClass;
trait AetherEnum
{
/**
* 获取所有枚举值数组(严格保持定义顺序).
* @return array<int|string> 枚举值集合
*/
public static function values(): array
{
self::validateEnumStructure();
$values = [];
foreach (self::cases() as $case) {
$values[] = $case->value;
}
return $values;
}
/**
* 获取所有枚举描述数组与values()顺序一一对应).
* @return array<string> 描述文本集合
*/
public static function descriptions(): array
{
self::validateEnumStructure();
$descriptions = [];
foreach (self::cases() as $case) {
$descriptions[] = $case->description();
}
return $descriptions;
}
/**
* 获取值-描述映射数组(用于下拉选择等场景).
* @return array<int|string, string> 键为枚举值,值为描述文本
*/
public static function valueMap(): array
{
self::validateEnumStructure();
$map = [];
foreach (self::cases() as $case) {
$map[$case->value] = $case->description();
}
return $map;
}
/**
* 根据值获取枚举实例(严格模式).
* @param int|string $value 枚举值
* @return AetherEnum 枚举实例
*/
public static function fromValue(int|string $value): self
{
self::validateEnumStructure();
// 检查值类型是否与枚举类型匹配基于第一个case的类型
$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;
}
/**
* 根据描述获取枚举实例(精确匹配).
* @param string $description 描述文本
* @return null|AetherEnum 匹配的枚举实例无匹配时返回null
*/
public static function fromDescription(string $description): ?self
{
self::validateEnumStructure();
foreach (self::cases() as $case) {
if ($case->description() === $description) {
return $case;
}
}
return null;
}
/**
* 检查值是否为有效的枚举值(严格类型检查).
* @param int|string $value 待检查的值
* @return bool 是否有效
*/
public static function isValidValue(int|string $value): bool
{
self::validateEnumStructure();
foreach (self::cases() as $case) {
if ($case->value === $value) { // 严格相等,避免类型松散匹配
return true;
}
}
return false;
}
/**
* 校验枚举结构合法性替代__init私有静态方法.
*/
private static function validateEnumStructure(): void
{
// 检查当前类是否为枚举
if (! (new ReflectionClass(self::class))->isEnum()) {
throw new InvalidArgumentException(sprintf(
'AetherEnum trait仅允许枚举类使用%s不是枚举',
self::class
));
}
// 检查枚举是否实现了description()方法
if (! method_exists(self::class, 'description')) {
throw new InvalidArgumentException(sprintf(
'枚举类%s必须实现description()方法(返回字符串描述)',
self::class
));
}
// 检查description()方法返回值是否为字符串
$sampleCase = self::cases()[0] ?? null;
if ($sampleCase && ! is_string($sampleCase->description())) {
throw new InvalidArgumentException(sprintf(
'枚举类%s的description()方法必须返回字符串',
self::class
));
}
}
}