3v4l.org

run code in 300+ PHP versions simultaneously
<?php #[Attribute(Attribute::TARGET_CLASS_CONSTANT)] final class SuitInfo { public function __construct(public readonly string $symbol, public readonly string $color) { } } trait EnumDetailsTrait { final protected function getAttribute(string $className): mixed { $reflection = new ReflectionClassConstant($this::class, $this->name); $classAttributes = $reflection->getAttributes($className); return match (count($classAttributes)) { // Return a blank details 0 => new $className(), // Return the provided information 1 => reset($classAttributes)->newInstance(), // PHP doesn't enforce not-repeatable for attributes, so we have to default => throw new RuntimeException(sprintf('%1$s cases must have a single attribute of %2$s ', self::class, $className)), }; } } enum Suit: string { use EnumDetailsTrait; #[SuitInfo('♣', 'black')] case Clubs = 'clubs'; #[SuitInfo('♦', 'red')] case Diamonds = 'diamonds'; #[SuitInfo('♥', 'red')] case Hearts = 'hearts'; #[SuitInfo('♠', 'black')] case Spades = 'spades'; public function getSymbol(): string { return $this->getAttribute(SuitInfo::class)->symbol; } public function getColor() : string { return $this->getAttribute(SuitInfo::class)->color; } } class Card { public function __construct(public readonly string $value, public readonly Suit $suit){} } $myCard = new Card('Q', Suit::Clubs); echo $myCard->suit->getSymbol(); echo PHP_EOL; echo $myCard->suit->getColor();

preferences:
28.6 ms | 405 KiB | 5 Q