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

Reply via email to