readonly-властивість (PHP 8.1) можна присвоїти лише один раз і лише всередині класу - зазвичай у конструкторі. Далі будь-яка спроба змінити її кидає Error. readonly class (PHP 8.2) робить такими всі властивості класу.
final readonly class Money
{
public function __construct(
public int $amount,
public string $currency,
) {}
}
Що варто знати:
readonlyзахищає саму властивість, а не вміст об'єкта в ній: якщо там лежить змінюваний об'єкт, його поля змінювати можна.- Властивість мусить мати тип, і значення за замовчуванням у неї бути не може.
Змінені копії («withers»). Незмінний об'єкт не редагують, а створюють новий з іншим значенням:
public function withAmount(int $amount): static
{
return new static($amount, $this->currency);
}
Через clone раніше так не виходило: копія мала ту саму вже ініціалізовану властивість. З PHP 8.3 readonly-властивості можна переприсвоїти в __clone(), а PHP 8.5 додав clone з переліком нових значень - clone($this, ['amount' => $amount]), без ручного конструктора.
Навіщо це все: незмінні value objects (гроші, діапазони дат, адреси) можна спокійно передавати куди завгодно - ніхто не змінить їх «під ногами» в іншому місці коду.