According to the RFC on Enumerations, attributes can be added to cases by using Attribute::TARGET_CLASS_CONSTANT. (Actually, the RFC says TARGET_CLASS_CONST but that is either a typo or a later change.) I'm having trouble trying to access them using Reflection, however.
Given this setup:
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class TestAttribute
{
public function __construct(public string $value)
{
}
}
enum TestNum
{
#[TestAttribute('alpha value')]
case ALPHA;
#[TestAttribute('beta value')]
case BETA;
}
I would expect the following code to give me an array with a single attribute, however it returns an empty array.
$obj = TestNum::ALPHA;
$reflection = new ReflectionClass($obj);
$classAttributes = $reflection->getAttributes(TestAttribute::class);
var_dump($classAttributes);
Demo here: https://3v4l.org/uLDVQ#v8.1.2
I found a test-case for this in the PHP src, however the usage isn't what I'd expect. Instead of using an instance, I need to decompose it:
var_dump((new \ReflectionClassConstant(TestNum::class, 'ALPHA'))->getAttributes(TestAttribute::class)[0]->newInstance());
Demo here: https://3v4l.org/BsA9r#v8.1.2
I can use that format, but it feels really hacky since I'm pretty much using reflection inside of reflection:
var_dump((new \ReflectionClassConstant($obj::class, $obj->name))->getAttributes(TestAttribute::class)[0]->newInstance());
Demo here: https://3v4l.org/YY6Oa#v8.1.2
Specifically, the new \ReflectionClassConstant($obj::class, $obj->name) pattern seems strangely boilerplate.
Is there another way to access individual enumeration case attributes that I'm missing?
#[Attribute( Attribute::TARGET_CLASS_CONSTANT )]
class TestAttribute {
public function __construct(public string $value) {
}
}
enum TestNum {
#[TestAttribute( 'alpha value' )]
case ALPHA;
#[TestAttribute( 'beta value' )]
case BETA;
}
$obj = TestNum::ALPHA;
$ref = new ReflectionEnumUnitCase($obj::class, $obj->name);
$argument = $ref->getAttributes('TestAttribute')[0]->getArguments()[0];
print_r($argument); // Prints: 'alpha value'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With