On the face of it, the new readonly properties in PHP 8.1 seem really useful for Value Objects and Data Transfer Objects: both should be immutable; setting property values should always be handled in the constructor, so no setters; and with readonly properties, we no longer need to code boilerplate getter methods; so we only need to code a comparison method for value objects. Between constructor property promotion introduced in PHP 8, and readonly properties introduced in PHP 8.1, we can reduce the code (skipping the comparison for brevity) for defining a Money class from
class Money {
protected int $value;
protected Currency $currency;
public function __construct(int $value, Currency $currency)
{
$this->value = $value;
$this->currency = $currency;
}
public function getValue(): int {
return $this->value;
}
public function getCurrency(): Currency {
return $this->currency;
}
}
to a much more simplistic
class Money {
public function __construct(
public readonly int $value,
public readonly Currency $currency
) {}
}
and then we directly access the value and currency of the object externally as object properties, rather than needing to use the getter methods of the original version.
The new version of our Money class looks so much cleaner: we’ve reduced the cognitive overhead, and we’ve eliminated a lot of boilerplate code – readonly properties FTW, right?