On Thu, Jul 3, 2025, at 12:54 PM, Andreas Hennings wrote:
>> > A setter method injection is what I did in AttributeUtils, because it was >> > the only real option. Alternatively, I suppose core could use property >> > setter injection (either a magically named property like $__reflector, or >> > a property that itself has an attribute on it, etc.). That would allow it >> > to be set before the constructor is called, and with property hooks would >> > allow processing either immediately or later in the constructor. The >> > downside here is that Attribute are, generally, serializable, but a >> > Reflection object is not. So if someone wanted a serializable attribute >> > they would have to accept the property, use it, and then remember to unset >> > it at some point. That's clumsy. >> > >> > --Larry Garfield >> > >> >> As someone that's written yet another userland "solution" for this problem, >> I have an alternative solution, based somewhat on an internalised concept >> of "never store Reflectors". >> >> Introduce an interface "ReflectorAttribute" (bike shedding to come); which >> accepts a single Reflector argument. >> >> If the attribute implements the interface, the method is called immediately >> following instantiation. > > Yep, this is the "method injection" mentioned by Larry, or what I > referred to as "setter injection". > I have not seen your library, but I assume that's where it is going. Yes, that is what AttributeUtils does today, almost exactly. From the docs: #[\Attribute] class AttribWithName implements FromReflectionClass { public readonly string $name; public function __construct(?string $name = null) { if ($name) { $this->name = $name; } } public function fromReflection(\ReflectionClass $subject): void { $this->name ??= $subject->getShortName(); } } (There's a different interface for each type of thing an attribute can be put on because the parameter type is different.) --Larry Garfield