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.

Reply via email to