rfc:readonly_classes

PHP RFC: Readonly classes

Introduction

PHP 8.1 added support for readonly properties via PHP RFC: Readonly properties 2.0. However, it's still not easy to declare (quasi-)immutable classes, especially if they contain many properties. Therefore, this RFC proposes to add support for readonly classes.

Proposal

The usage of the readonly modifier added by PHP RFC: Readonly properties 2.0 is extended to classes:

readonly class Test {
    public string $prop;
}

Doing so will implicitly mark all instance properties of a class as readonly. Furthermore, it will prevent the creation of dynamic properties.

readonly class Foo
{
    public int $bar;
 
    public function __construct() {
        $this->bar = 1;
    }
}
 
$foo = new Foo();
$foo->bar = 2;
// Fatal Error: Uncaught Error: Cannot modify readonly property Foo::$bar
 
$foo->baz = 1;
// Fatal Error: Uncaught Error: Cannot create dynamic property Foo::$baz

PHP RFC: Deprecate dynamic properties added support for the #[AllowDynamicProperties] attribute which makes it possible to create dynamic properties without triggering errors. In order not to violate the read-only constraint, marking readonly classes with the above attribute is a compile-time error:

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

Restrictions

As neither untyped, nor static properties are covered by the Readonly properties RFC, readonly classes cannot declare them either:

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

Inheritance

Similarly how overriding of readonly properties works, a readonly class can only extend a readonly parent:

readonly class A {}
readonly class B extends A {} // valid

But both of the following are illegal:

readonly class 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

A ReflectionClass::isReadOnly() method is added, which reports whether a class is declared as read-only. Additionally, ReflectionClass::getModifiers() will also include the ReflectionClass::IS_READONLY flag.

Backward Incompatible Changes

None.

Errata

  • https://github.com/php/php-src/issues/9285: It used to be possible to add non-readonly properties to readonly classes via traits. As on PHP 8.2 RC 1, traits cannot be used by readonly classes if they define any non-readonly property, otherwise a compilation error is emitted.

Vote

Voted started on 2022-04-27, ending on 2022-05-11

Add readonly classes as proposed?
Real name Yes No
asgrim Image 
ashnazg Image 
beberlei Image 
bukka Image 
bwoebi  Image
crell Image 
cschneid  Image
derick Image 
didou Image 
diegopires Image 
dmitry  Image
dragoonis Image 
galvao Image 
geekcom Image 
girgias Image 
jbnahan Image 
jhdxr  Image
kocsismate Image 
lcobucci Image 
lstrojny Image 
lufei Image 
mauricio Image 
mgocobachi Image 
nicolasgrekas Image 
ocramius Image 
pierrick Image 
pollita  Image
reywob  Image
santiagolizardo Image 
sebastian Image 
sergey Image 
stas  Image
theodorejb Image 
weierophinney Image 
wyrihaximus Image 
Final result: 28 7
This poll has been closed.
rfc/readonly_classes.txt · Last modified: by 127.0.0.1

Image