Skip to content
PHP News
Search
Declined PHP 8.6

Allow Reassignment of Promoted Readonly Properties in Constructor

Lets a constructor reassign a promoted readonly property exactly once, so you can validate or normalize it without dropping promotion.

Allow Reassignment of Promoted Readonly Properties in Constructor?

Primary vote · 2/3 majority

11 Yes 10 No 6 abstain 52% approval

This poll has closed.

It was declined. The vote was 11 to 10, with 6 abstaining, well short of the two-thirds majority it needed. Voting closed on April 7, 2026.

Summary

Constructor promotion lets you declare a property right in the constructor's parameter list, and readonly properties can only be set once. Put the two together and you hit a wall: PHP assigns the promoted property before your constructor body runs, so you can't clean up the value afterward. This RFC from Nicolas Grekas would have let you reassign a promoted readonly property one time, inside the constructor.

Before and after

Today this fails:

class Point {
    public function __construct(
        public readonly float $x = 0.0,
        public readonly float $y = 0.0,
    ) {
        // ERROR: Cannot modify readonly property Point::$x
        $this->x = abs($x);
        $this->y = abs($y);
    }
}

To make it work now, you have to drop promotion and declare the properties by hand. Property hooks are another option, but they run on every assignment and lose the readonly guarantee.

With this RFC, the code above would work, and new Point(-5.0, -3.0) would give you 5.0 and 3.0. A second reassignment would still throw an error:

$this->value = 'first';   // OK
$this->value = 'second';  // Error: Cannot modify readonly property

The rules

  • It only applies to promoted readonly properties. Regular readonly properties don't change.
  • You get one reassignment, and only through $this.
  • It works while the constructor is running, including in methods and closures the constructor calls.
  • Only the class that promoted the property gets the extra write. A child class can't use it from its own constructor.
  • Calling __construct() again on a finished object can't reopen the property.
  • private(set) and protected(set) still apply.
  • Operations like $this->count++ count as the one reassignment.

What it means for existing code

Nothing would break, since the RFC only allows code that is an error today. Static analysis tools and IDEs would need updates to treat these reassignments as valid.