Understanding PHP’s New Readonly Classes: Benefits, Syntax, and Limitations

The PHP RFC introduces readonly classes, allowing all properties of a class to be immutable, prohibiting dynamic and static properties, and providing reflection support, with examples, restrictions, inheritance rules, and compatibility notes, helping developers write safer, more robust code.

21CTO
21CTO
21CTO
Understanding PHP’s New Readonly Classes: Benefits, Syntax, and Limitations

Introduction

PHP 8.1 added the readonly property modifier, and the new RFC extends this capability to entire classes, enabling developers to declare classes whose properties are immutable without marking each property individually.

Proposal

The RFC proposes that the readonly keyword can be applied to class definitions, making every property of the class readonly.

Basic Example

readonly class Test {
    public string $prop;
}

This makes all properties of the class readonly and also forbids the creation of dynamic properties.

Usage Example

readonly class Foo {
    public int $bar;

    public function __construct() {
        $this->bar = 1;
    }
}

$foo = new Foo();
$foo->bar = 2; // Fatal Error: Cannot modify readonly property Foo::$bar
$foo->baz = 1; // Fatal Error: Cannot create dynamic property Foo::$baz

Dynamic properties are prohibited, and attempts to modify readonly properties result in fatal errors.

Interaction with Deprecate Dynamic Properties RFC

The RFC that deprecates dynamic properties ( #[AllowDynamicProperties]) cannot be applied to readonly classes:

#[AllowDynamicProperties]
readonly class Foo {}
// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo

Restrictions

Readonly classes cannot declare untyped properties or static properties:

readonly class Foo {
    public $bar;            // Fatal error: Readonly property Foo::$bar must have type
    public static int $baz; // Fatal error: Readonly class Foo cannot declare static properties
}

Extension

Readonly classes can extend other readonly classes, but a non‑readonly class cannot extend a readonly class, and a readonly class cannot extend a non‑readonly class:

readonly class A {}
readonly class B extends A {}

class B extends A {} // Fatal error: Non-readonly class B cannot extend readonly class A

class A {}
readonly class B extends A {} // Fatal error: Readonly class B cannot extend non-readonly class A

Reflection Support

Two new reflection features are added: ReflectionClass::isReadOnly() – checks if a class is readonly. ReflectionClass::getModifiers() – includes the IS_READONLY flag.

Compatibility

There are no backward‑incompatible changes introduced by this RFC. The feature is forward compatible, and PHP 9.0 will eventually forbid access to undefined properties, which aligns with the readonly class behavior.

Summary

Readonly classes allow a class to be instantiated only once; its properties cannot be changed afterward, effectively providing immutable objects. Example with constructor property promotion:

readonly class Foo {
    public function __construct(public int $bar) {}
}

$foo = new Foo(1); // OK
$foo->bar = 2; // Fatal error

While readonly classes cannot have static or dynamic properties and require typed properties, they help prevent accidental overwrites and enable more robust, secure code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ReflectionPHPimmutabilityreadonly classes
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.