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.
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::$bazDynamic 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 FooRestrictions
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 AReflection 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 errorWhile readonly classes cannot have static or dynamic properties and require typed properties, they help prevent accidental overwrites and enable more robust, secure code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
