Nick Sdot has had the Readonly Property Defaults RFC accepted for PHP 8.6. The vote closed on August 6, 2026 with 24 in favor, none against, and 5 abstentions. Starting in 8.6, a readonly property can declare a default value in the class body rather than being assigned in the constructor.

Until now, a default on a readonly property was a compile-time error, so a class with fixed values had to route them through a constructor that took no arguments and set them one by one. Announcing the result on X, Nick called it "One weirdness less, yay."

What It Does

The restriction on default values is gone. A readonly property can be declared with its value inline:

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

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

The same applies to a readonly class, which is where the constructor boilerplate was heaviest:

final readonly class SourceOneChangelogIngestor implements IngestorBlueprint
{
    public string $name = 'Source One';
    public string $stub = 'stubs/output.md';
    public string $path = 'source-one/changelog/%s/%s';
    public array $steps = [
        ParserShapeA::class,
        HandleShapeA::class,
    ];
}

A child class can also override a parent's default:

abstract class ParentRule
{
    public readonly int $priority = 1;
}

final class ChildRule extends ParentRule
{
    public readonly int $priority = 2;
}

The default counts as the initializing assignment. The property is initialized before the constructor runs, so a later write to it fails the same way a second write always has.

The Vote

The vote asked:

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

It ran from July 24 to August 6, 2026 and finished 24 to 0, with 5 abstentions. The RFC is marked Accepted and targets PHP 8.6.

What It Means for Your Code

The change is additive, so existing code keeps working. A few behaviors are worth knowing before you reach for it:

  • Promoted constructor properties are unchanged. A default on a promoted parameter is still a parameter default, not a property default.
  • You cannot unset one. Calling unset($this->prop) on a readonly property that has a default throws an error.
  • Clone can reinitialize it once. A __clone() method may assign the property a single time.
  • Serialization includes it. Properties with defaults appear in serialized data and can be restored on unserialize.

Readonly Property Defaults joins a growing 8.6 list. You can follow the rest of our PHP 8.6 coverage as the remaining RFCs close their votes.

For the full reasoning, the edge cases, and the implementation notes, read the RFC on the PHP wiki.