Re: [RFC] Primary Constructors

From: Date: Mon, 29 Jun 2026 20:22:46 +0000
Subject: Re: [RFC] Primary Constructors
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-131622@lists.php.net to get a copy of this message
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

« previous php.internals (#131622) next »