Allow hooks in `readonly` promoted properties
| From: | Nick | Date: | Mon, 02 Jun 2025 12:49:39 +0000 |
| Subject: | Allow hooks in `readonly` promoted properties | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-127529@lists.php.net to get a copy of this message | ||
Dear Internals,
I am sending my first message here. Thank you all for your hard work!
PHP has evolved amazingly over the past few years; I love it.
Promoted properties allow us to write very neat value objects, with almost no boilerplate.
Now, with property hooks, we can eliminate even more boilerplate.
However, there is a bummer.
When we want to use a set hook to add a simple mapper or validator, we are have to deal with
asymmetric visibility, and refactor the whole class.
Here in user land, I don't see a clear reason for that.
Ideally, I would simply like to handle what will be set without having to deal with the general
visibility of the class or its properties.
Currently, instead of:
```php
final readonly class Entry
{
public function __construct(
public string $word,
public string $slug,
public string $file,
public string $path,
public array $lemmas {
set(array $value) => array_map(static function (Lemma|array $lemma): Lemma {
return $lemma instanceof Lemma ? $lemma : new Lemma(...$lemma);
}, $value);
},
) {}
}
```
we must refactor our entire class and will arrive at:
```php
final class Entry // no more readonly
{
public function __construct(
public readonly string $word, // added readonly
public readonly string $slug, // added readonly
public readonly string $file, // added readonly
public readonly string $path, // added readonly
private(set) array $lemmas { // added visibility
set(array $value) => array_map(static function (Lemma|array $lemma): Lemma {
return $lemma instanceof Lemma ? $lemma : new Lemma(...$lemma);
}, $value);
},
) {}
}
```
The downsides are:
- the class can no longer be
readonly
- each property must be set to readonly
- hooked properties must use private(set)
There are many unrelated things we need to think about just to use a set hook.
The example object is tiny and already then feels so much denser.
Think of a bigger object if you like. For each added property, we once again must add the
readonly keyword.
Unnecessary noise, IMHO.
Personally, this puts me off adopting property hooks -- because right now, a good old factory method
is, subjectively, more clean/clear.
I believe promoted properties should allowed for readonly properties and in
readonly classes.
This would help us to avoid the unnecessary boilerplate like outlined above.
That said, I would greatly appreciate if internals could explore to allow readonly for
hooks in promoted properties in 8.5.
--
Cheers & thanks,
Nick