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