Re: [RFC idea] Target-aware attributes
| From: | Larry Garfield | Date: | Thu, 03 Jul 2025 21:43:36 +0000 |
| Subject: | Re: [RFC idea] Target-aware attributes | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-127871@lists.php.net to get a copy of this message | ||
On Thu, Jul 3, 2025, at 12:49 PM, Andreas Hennings wrote:
>> A setter method injection is what I did in AttributeUtils, because it was the only real
>> option.
>
> In my experience, this alternative leads to more complexity in
> attribute classes.
> The constructor needs to populate the attribute with temporary values,
> which are then replaced in that separate method.
> (I call that a "setter", but only because it behaves like one from the
> outside, internally we usually don't want to store the reflector).
>
> Also, we can never be fully sure whether an attribute instance is
> "complete" or not.
> If the attribute instance is coming from
> $reflection_attribute->newInstance(), we can be confident that the
> ->injectReflector() or has been called.
> But if the attribute was instantiated manually with "new ...", it
> could as well be incomplete.
> With ReflectionAttribute::getCurrentTargetReflector(), we can fail
> early in the attribute constructor, by throwing on NULL.
I ran into the "completeness problem" in AttributeUtils as well. In my case, it's
not just reflection; there's a whole bunch of other things that can be passed back to the
attribute to give it more context. My eventual solution was to also have a
Finalizable
interface that is guaranteed to be the last thing called, so the attribute can handle any
last-minute defaults. I don't love it, but given the severe limitations of
readonly it was the best I could do. (With aviz today, I could likely do better.)
Basically, any time you have multi-step construction you will have a period where the state is
potentially incomplete. While passing the reflection target in is one such multi-step case, there
are lots of others, so in advanced cases (most of what I do) the object will always have an
incomplete phase, and that's unavoidable. So I'm not *that* worried about there being a
brief incomplete-gap in time in core, because I'll always have one anyway, and I've
already figured out how to handle it.
--Larry Garfield