On Mon, Jun 29, 2026 at 12:56 PM Rob Landers <[email protected]> wrote:
> > > On Mon, Jun 29, 2026, at 12:27, Lynn wrote: > > > > On Mon, Jun 29, 2026 at 2:20 AM Rob Landers <[email protected]> wrote: > > > Hello internals, > > I'd like to put forward Primary Constructors > <https://wiki.php.net/rfc/primary-constructors> for comment. > > An implementation PR will be opened later today (UTC), and the RFC updated > with this discussion thread. > > — Rob > > > I don't see any mention of anonymous classes, I assume they aren't > compatible syntax wise? > > > Hi Lynn, > > That's a good observation! Originally, I had a whole section and decided > to strip it, then forgot to add it back as non-supported and future scope. > FWIW, I was originally going to support them with something like: > > $arg = 'foo'; > $class = new class(public int $x = $arg) {} > > > Which desugars to: > > $arg = 'foo'; > $class = new class($arg) { > public function __construct(public int $x) {} > } > > > There are a lot of caveats, which is why I dropped it for future scope: > > 1. it would require types on the input parameters to disambiguate > between arguments and properties > 2. it gets weird if you don't specify a default value for the property > and makes it ambiguous as a constructor > 3. which begs the question of always having a default > > In essence, it deserves its own RFC because there is a lot of subtlety and > only makes sense in the context that primary constructors exist in the > first place. > > I'll address it in the RFC, thanks! > > — Rob > I think the only thing that needs to be solved for anonymous classes would be the syntax. Seeing there's always a visibility/type in property promotion, I think it should be clear it's going to be style (A) or (B) based on the syntax as you can't mix. I can't see a scenario where you would write: $class = new class(public int $x) {} Where as the following would be just fine: $class = new class(public int $x = 0) {}; // construct with property $x being 0 $class = new class(public int|null $x = null) {}; // construct with property $x being null $class = new class(public int $x = $x) {}; // construct with $x from local scope into property $x $class = new class(public int $x = $this->x) {}; // construct with $this->x from the instance scope $class = new class(public int $x = self::$x) {}; // construct with $this->x from the static self scope Bonus points if the body becomes optional: $class = new class(public int $x = 0, public int $y = 0); This would be the existing style and remains unchanged $class = new class($localScope) {}; Mixing would error as you can't pick both: $class = new class(public int $x = 0, $y) {}; // Nothing handles $y as no body is allowed $class = new class($x, public int $y = 0) {}; // Can't allow the latter as $x requires a body to do something Perhaps this isn't as simple as I think it is, but this would be a nice + to have in this RFC. I think it's fine to keep the initial implementation rather restrictive, it can always be improved upon in the future.
