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

Reply via email to