Default value for readonly properties
| From: | Claude Pache | Date: | Fri, 07 Jun 2024 09:07:04 +0000 |
| Subject: | Default value for readonly properties | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-123535@lists.php.net to get a copy of this message | ||
Hi,
As of today, readonly properties cannot have a default value:
```php
class UltimateQuestion {
readonly int $answer = 42; // Fatal error: Readonly property Question::$answer cannot have
default value
}
```
The rationale given in the original RFC (https://wiki.php.net/rfc/readonly_properties_v2) was:
As the default value counts as an initializing assignment, a readonly property with a default value
is essentially the same as a constant, and thus not particularly useful. The notion could become
more useful in the future, if new expressions are allowed as property default values. At the same
time, depending on how exactly property initialization would work in that case, having a default
value on a readonly property could preclude userland serialization libraries from working, as they
would not be able to replace the default-constructed object. Whether or not this is a concern
depends on whether the property is initialized at time of object creation, or as an implicit part of
the constructor (or similar). As these are open questions, the conservative choice is to forbid
default values until these questions are resolved.
A new fact is that properties will be able to be declared in interface since PHP 8.4 (as introduced
in the recently accepted property hooks RFC). It is true that, for an individual class, a readonly
property is functionally equivalent to a constant. But my class implements an interface (or, before
8.4, follows a non-written protocol), and whether that particular implementation choose to always
hold the same value for a specific property is irrelevant.
```php
interface Question {
public int $answer { get; }
}
class UltimateQuestion implements Question {
readonly int $answer = 42;
}
```
Therefore I think it is reasonable for readonly properties to accept default values.
About the concern given in the original RFC: “having a default value on a readonly property could
preclude userland serialization libraries from working, as they would not be able to replace the
default-constructed object”... TBH, as I almost never serialise my objects, and even less often
customise serialisation, I can only guess what the effective issue is. My best guess is that a
custom
__unserialize() method would not be able to reinstate the incriminated readonly
properties, because those would already have been initialised with the default value. If this is the
case, a solution is to do for __uninitialize() the same thing that we have done for
__clone(), see: https://wiki.php.net/rfc/readonly_amendments#proposal_2readonly_properties_can_be_reinitialized_during_cloning
—Claude