Constructor property promotion lets you declare a property right in the constructor's parameter list, so you don't have to write it twice. PHP 8.4 added final properties alongside property hooks, but you couldn't use final on a promoted property. This RFC from Daniel Scherzer fixes that.

Show me

Before, you had to declare a final property the long way:

class User
{
    final public string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }
}

With this RFC, you can mark the constructor parameter as final:

class User
{
    public function __construct(final string $name) {}
}

The parameter becomes a promoted property, and that property is final, so a child class can't override it.

How it works

  • final alone is enough. A final property is public by default, so you don't need to add public when you promote it.
  • You can still add visibility. final public, final protected and similar combinations all work.
  • It works with other features. You can combine final with asymmetric visibility (like private(set)) and with property hooks.

The motivation is the same as for promotion itself: it cuts down on repeated code.

What it means for existing code

Nothing breaks. Before this RFC, final on a constructor parameter was an error, so no working code used it and everything that ran before runs the same way.

Static analyzers and IDEs need updates so they understand final on constructor parameters.

The vote

It passed 25 to 0, clearing the two-thirds majority it needed. Voting closed on June 9, 2025, and the change shipped in PHP 8.5.