On Fri, Apr 5, 2024, at 2:20 PM, Joel Wurtz wrote:
>> Would it make sense to not only add this for ReflectionAttribute, but also 
>> Function and/or others?
>
> There may be case where this makes sense but not necessarily in the use 
> case that i explain, and don't want to add more to this proposal, it's 
> also missing in ReflectionParameter, ReflectionProperty and certainly 
> many others if we go on this path then there is a lot of changes to 
> apply and will induce more friction for this proposal, i prefer to add 
> small parts so we don't deviate from the original use case.
>
>> Do you have an example of how you expect this to be used?  I'm having a hard 
>> time understanding how I'd leverage this.  (I maintain an attribute 
>> enhancement library, Crell/AttributeUtils, so I've hit a lot of edge cases 
>> in attribute design.)
>
> Sure, let's say we have the following class
>
> #[CustomAttribute(foo: 'foo')
> #[CustomAttribute(foo: 'foo')
> class Entity {}
>
> And that later i have something that read those attributes, but i want 
> to throw an Exception when multiple attribute defined the same value 
> for the foo property (as it should be unique in my use case), i would 
> not be able to do that in the constructor since i don't have the 
> context of others attributes in this case, so i want to throw a custom 
> exception explaining it's caused by the attribute "CustomAttribute" in 
> the file "Entity.php" at line 4, as there is the same value in the file 
> "Entity.php" at line 3
>
> If I throw an exception without this message the error will pinpoint to 
> where I threw the exception and it may be confusing for the end user, 
> by having this he will know where to look and what to modify to make 
> its code correct.

OK, so the idea is you could do something like:

$rClass = new ReflectionClass(Entity::class);
$as = $rClass->getAttributes();
$attribs = array_map(fn(ReflectionAttribute $r) => $r->getInstance(), $as);
$values = array_map(fn(CustomAttribute $r) => $r->foo, $attribs);

if ($values is not unique) {
  $msg = sprintf('You have too many %s on in file %s on line %d', 
Entity::class, $as[0]->getFile(), $as[0]->getLine());
  throw new Exception($msg);
}

(Or something like that.)

That works, I suppose, but couldn't that also be done with 
ReflectionClass::getStartLine() and ReflectionClass::getFileName()?  

--Larry Garfield

Reply via email to