Laravel中为Ben Sampo Enum添加自定义属性及本地化方案
解决Ben Sampo Enum扩展包自定义属性读取问题
1. 修正自定义属性读取Trait
原GetEnumAttributes trait无法正确读取属性值,核心问题是未从枚举项的反射注解中提取对应值,重新实现如下:
namespace App\Enums\Traits; use BenSampo\Enum\Enum; use ReflectionClass; trait GetEnumAttributes { /** * 获取单个枚举实例的所有自定义属性 * @return array */ public function getAttributes(): array { $reflectionClass = new ReflectionClass($this); $property = $reflectionClass->getProperty($this->name); $attribute = $property->getAttributes(\App\Enums\Attributes\EnumAttribute::class)[0] ?? null; return $attribute ? $attribute->getArguments() : []; } /** * 通过枚举值获取指定属性 * @param int|string $value * @param string $attributeName * @return mixed|null */ public static function getAttribute(int|string $value, string $attributeName) { $enum = static::fromValue($value); return $enum->getAttributes()[$attributeName] ?? null; } /** * 获取color属性的快捷方法 * @param int|string $value * @return string|null */ public static function getColor(int|string $value): ?string { return static::getAttribute($value, 'color'); } /** * 获取所有带自定义属性的枚举实例 * @return array */ public static function getCustomInstances(): array { $instances = []; foreach (static::cases() as $case) { $instances[] = array_merge([ 'value' => $case->value, 'name' => $case->name, 'description' => $case->description, ], $case->getAttributes()); } return $instances; } // 单个枚举实例的属性快捷访问 public function getColor(): ?string { return $this->getAttributes()['color'] ?? null; } public function isFinal(): ?bool { return $this->getAttributes()['isFinal'] ?? null; } }
2. 定义自定义属性注解类
创建统一的注解类来标记枚举项的自定义属性,确保反射能正确识别:
namespace App\Enums\Attributes; use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] class EnumAttribute { public function __construct( public ?string $color = null, public ?bool $isFinal = false ) {} }
3. 实现带自定义属性的Status枚举
继承Ben Sampo Enum并集成上述Trait和注解,同时保留本地化特性:
namespace App\Enums; use BenSampo\Enum\Enum; use App\Enums\Attributes\EnumAttribute; use App\Enums\Traits\GetEnumAttributes; final class Status extends Enum { use GetEnumAttributes; #[EnumAttribute(color: '#4CAF50', isFinal: false)] const Initial = 1; #[EnumAttribute(color: '#FFC107', isFinal: false)] const Processing = 2; #[EnumAttribute(color: '#F44336', isFinal: true)] const Completed = 3; // 保留Ben Sampo Enum的本地化描述 public static function descriptions(): array { return [ self::Initial => __('初始状态'), self::Processing => __('处理中'), self::Completed => __('已完成'), ]; } }
4. 调用方式测试
现在可以按需求自由获取属性:
// 通过枚举值获取color $initialColor = Status::getColor(1); // 返回 #4CAF50 // 通过枚举实例获取color $processingColor = Status::Processing->getColor(); // 返回 #FFC107 // 判断是否为最终状态 $isCompletedFinal = Status::Completed->isFinal(); // 返回 true // 获取所有带自定义属性的枚举实例 $allStatus = Status::getCustomInstances(); // 返回示例结构: // [ // ['value' => 1, 'name' => 'Initial', 'description' => '初始状态', 'color' => '#4CAF50', 'isFinal' => false], // ['value' => 2, 'name' => 'Processing', 'description' => '处理中', 'color' => '#FFC107', 'isFinal' => false], // ['value' => 3, 'name' => 'Completed', 'description' => '已完成', 'color' => '#F44336', 'isFinal' => true], // ]
内容的提问来源于stack exchange,提问作者ERasekh
相关产品推荐
相关产品推荐

