Fully tested, phpstan level 9 compliant.
composer require zrnik/php-attribtue-reflection
I use attributes on enum cases a lot. It's a good way to put metadata on the cases. Let's look at this example:
<?phpnamespaceZrnik\Example;
useReflectionClass;
useRuntimeException;
enum CaseToSolve
{
#[AttributeToFind('AnyParameter')]
case FirstCase;
#[AttributeToFind('DifferentParameter')]
#[AnotherAttribute('WhateverIsHere')]
case SecondCase;
case ThirdCase;
publicfunctiongetParameter(): string
{
$reflection = newReflectionClass(self::class);
$caseReflection = $reflection->getReflectionConstant($this->name);
if($caseReflection === false) {
thrownewRuntimeException('case not found');
}
foreach ($caseReflection->getAttributes() as$reflectionAttribute) {
if ($reflectionAttribute->getName() === AttributeToFind::class) {
/** @var AttributeToFind $attributeToFindInstance */$attributeToFindInstance = $reflectionAttribute->newInstance();
return$attributeToFindInstance->customValue;
}
}
thrownewRuntimeException(
sprintf(
'attribute "%s" not found on "%s"!',
AttributeToFind::class,
$this->name
)
);
}
}You probably know what its meant to do:
CaseToSolve::FirstCase->getParameter(); // 'AnyParameter'
CaseToSolve::SecondCase->getParameter(); // 'DifferentParameter'
CaseToSolve::ThirdCase->getParameter(); // RuntimeExceptionThis is what this library does, it just returns the attribute value. Now let's see how this code would work with this library:
<?phpnamespaceZrnik\Example;
useZrnik\AttributeReflection\AttributeReflection;
useZrnik\AttributeReflection\AttributeReflectionException;
enum SolvedCase
{
#[AttributeToFind('AnyParameter')]
case FirstCase;
#[AttributeToFind('DifferentParameter')]
#[AnotherAttribute('WhateverIsHere')]
case SecondCase;
case ThirdCase;
/** * @return string * @throws AttributeReflectionException */publicfunctiongetParameter(): string
{
return AttributeReflection::getClassConstantAttribute(
AttributeToFind::class,
self::class,
$this->name
)->customValue;
}
}The getParameter method is much better, isn't it? Works the same:
SolvedCase::FirstCase->getParameter(); // 'AnyParameter'
SolvedCase::SecondCase->getParameter(); // 'DifferentParameter'
SolvedCase::ThirdCase->getParameter(); // \Zrnik\AttributeReflection\AttributeReflectionException