Skip to content
PHP News
Search
Implemented PHP 8.6

Readonly Property Defaults

Lets readonly properties declare default values, so a class can meet a get-only interface property with a fixed value.

Allow readonly properties to have default values as outlined in the RFC?

Primary vote · 2/3 majority

24 Yes 0 No 5 abstain 100% approval

This poll has closed.

Accepted 24 to 0, with 5 abstaining, clearing the two-thirds majority it needed. Voting closed on August 7, 2026, and the change is merged for PHP 8.6.

Summary

Until now, a readonly property couldn't have a default value. The original readonly properties RFC called such a property "not particularly useful," since it would behave like a constant. This RFC from Nick Sdot removes that restriction without adding any new syntax. It just drops the compile-time check that rejected it.

Why now

PHP 8.4 added properties on interfaces, so an interface can now require a readable property with { get; }. A readonly property with a default is a clean way to satisfy that requirement, giving you a fixed value with no constructor and no getter.

interface Rule
{
    public string $className { get; }
}

final class RuleA implements Rule
{
    public readonly string $className = SomeParser::class;
}

The same works in a readonly class, since all of its properties are readonly.

How it behaves

The default counts as the first and only write, and the property is set before the constructor runs. That means any later write fails, even one from the constructor:

final readonly class Rule
{
    public string $className = SomeParser::class;

    public function __construct(string $className) {
        $this->className = $className; // Error: Cannot modify readonly property Rule::$className
    }
}

A few more rules from the RFC:

  • A child class can redeclare the property with its own default.
  • You can't unset() the property because it's already initialized, so the lazy-loading __get() trick doesn't work here.
  • __clone() and clone-with can still change the value once, like any readonly property.
  • Unserializing can restore a different value from serialized data.
  • Two traits that give the same property different defaults can't be used together.
  • It satisfies a { get; } interface property, but not { get; set; }.

What it means for existing code

Nothing breaks, because code that failed to compile before now compiles. IDEs and static analysis tools that flag these defaults as errors will need an update.

Our coverage

  • PHP 8.6 Beta 1

    PHP 8.6 Beta 1

    · PHP Core