Re: [PHP-DEV] [RFC] Primary Constructors
[email protected] ("Rob Landers")
| Newsgroups | php.internals |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Jun 29, 2026, at 18:59, Larry Garfield wrote:
[snip]
> The RFC has no mention of attributes. An example of that would be helpful, even though I presume it's exactly what one would expect it to be.
This was an oversight. I'll add the logic there. This is how they work:
1. Attributes on promoted primary-constructor params are reflected on both (just like promoted properties):
1. ReflectionParameter
2. ReflectionProperty
2. Attributes on bare params remain parameter-only.
3. Target validation is context-sensitive, matching existing constructor promotion behavior:
1. `#[ParamAttr] public int $x` appears on the property too, but newInstance() from ReflectionProperty errors.
2. `#[PropAttr] public int $x` appears on the parameter too, but newInstance() from ReflectionParameter errors.
4. Attributes before a class remain class attributes and are not copied to the synthesized constructor.
The last one is debatable, but from what I can tell from grepping, putting attributes on constructors is a very rare thing (39 out of 56,546 constructors). However, class-level attributes are a more common thing. That being said, I'd be open to changing (4) to behave like properties/parameters where it gets attached to the class and the constructor.
> The one addition I would ask for is to note that in Kotlin and Swift, there is a post-primary-constructor initializer, called an `init` block. It has no body, but lets you do post-property-assignment stuff. It's basically an argument-free constructor. I think that would go a long way toward smoothing the concerns people have about this feature being too "locked down."
>
> If we don't want a new keyword for it, we could allow a __construct method that has NO arguments if there is a primary constructor. It would get called last, after everything else (including parent constructors if appropriate) has run. (Whether it's spelled `__construct() { ]]` or `__construct { }`, I don't have a strong opinion.) A __construct that does take arguments would still be a compile-time conflict with a primary constructor.
>
> --Larry Garfield
>
I believe this should be a follow-up RFC. In PHP, the child decides when to call the parent constructor — so "runs last, after parent constructors" requires defining a new sequencing contract, which is a real design decision that deserves its own discussion rather than a rider on this one. Beyond that, it also requires defining a syntax (you've sketched one approach, Nick another -- both are interesting and that's exactly why it needs its own discussion), rules (whether property lists should exist), and semantics. In essence, the description would be a large (probably half) of the current RFC.
— Rob