On Tue, Sep 29, 2020 at 3:57 PM Benjamin Eberlei <kont...@beberlei.de>
wrote:

> On Tue, Sep 29, 2020 at 3:45 PM Larry Garfield <la...@garfieldtech.com>
> wrote:
>
> > On Mon, Sep 28, 2020, at 12:06 PM, Benjamin Eberlei wrote:
> > > On Mon, Sep 28, 2020 at 4:35 PM Benjamin Morel <
> benjamin.mo...@gmail.com
> > >
> > > wrote:
> > >
> > > > On Mon, 28 Sep 2020 at 15:17, Nicolas Grekas <
> > nicolas.grekas+...@gmail.com>
> > > > wrote:
> > > >
> > > >> I assume the 80% case is properties, because attributes did not have
> > > >>> docblock annotations yet, that means this use-case isn't even
> > possible at
> > > >>> the moment. Yet annotations on properties are widespread (Doctrine
> > ORM,
> > > >>> symfony validator, ...).
> > > >>>
> > > >>
> > > >> I'm 100% with Benjamin here, this is what will be the most useful to
> > me
> > > >> also.
> > > >>
> > > >
> > > > To be clear, I don't have a strong opinion against yours, I'm just
> > > > pointing out the fact that even though it might be useful, it might
> > also be
> > > > confusing and create yet another WTF moment in PHP for developers.
> > Sure, it
> > > > might make more sense to apply to the property. Sure, so far
> > annotations
> > > > weren't possible on parameters. But is that obvious to the average
> > > > developer writing the attribute? A few years down the road, DI
> > containers
> > > > may have broad support for annotating parameters for injection. Will
> it
> > > > still be obvious then that an attribute on a promoted property
> applies
> > to
> > > > the property only?
> > > >
> > > > I do agree that applying the attribute to both the property and the
> > > > parameter will probably never be useful, though. So, throwing an
> > exception
> > > > and forcing the de-sugaring feels like the most sensible thing to do
> > for me
> > > > in this case!
> > > >
> > >
> > > I haven't checked if this is possible in the code doing the
> "desugering",
> > > but what if we had an attribute on the constructor that could specify
> > where
> > > the attributes should apply to?
> > >
> > > #[AttributePromotion(Attribute::TARGET_PROPERTY)]
> > > public function __construct(#[Foo] public string $bar) {}
> > >
> > > Then we could apply it to both by default, which is what is probably
> the
> > > expected approach, and users could change it to apply only to
> properties,
> > > which is what is the use-case that makes most sense.
> > >
> > > >
> > > > — Benjamin
> >
> > From a user experience POV, I'd almost expect the opposite.
> >
> > If I mark the attribute as being for properties, it gets applied to the
> > property.
> >
> > If I mark the attribute as being for parameters, it gets applied to the
> > parameter.
> >
> > If I mark it for both, or don't restrict it at all, it applies to both.
> >
> > That may not be how the logic is currently implemented but that's what as
> > a user I'd find least-surprising.
> >
>
> The problem with this approach is that it would require autoloading the
> attributes when they are assigned to either the internal property or
> parameter struct, but we have the design goal *not* to trigger autoloading
> unless newInstance() or getArguments() is called. What you could do in
> userland code is handle this case yourself and never newInstance()
> attributes that don't apply to the right "thing" (parameter vs property).
> but that would defer the problem to userland with some annoying piece of
> code.
>

So, as there seems to be resistance to applying the attribute to properties
only I only see a couple of options:

1. Forbid combining attributes and promotion.

2. Relax attribute validation for this case, as implemented in
https://github.com/php/php-src/pull/6244. I think if we otherwise stick to
the current behavior, this is what we should do to avoid false-positive
errors.

3. Disambiguate what is desired somehow. __construct(#[PropAttr] public int
$x) vs __construct(public #[ParamAttr] int $x). This is ... a bit too much
magic :)

Nikita

Reply via email to