Re: [PHP-DEV] [RFC] Primary Constructors

[email protected] (Lynn)
Newsgroups php.internals
Message-ID <CANS-=pedh6chH3jGg7Qc4GFY9g8Dhp6AbSPoCrgLqfafLfpKNw@mail.gmail.com>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.