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