Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Модификатор доступа readonly в PHP
readonly — это модификатор доступа для свойств классов, появившийся в PHP 8.1. Он позволяет объявлять свойства, которые могут быть инициализированы только один раз — либо при объявлении, либо в конструкторе класса. После инициализации значение такого свойства не может быть изменено.
Ключевые особенности readonly-свойств
- Однократная инициализация: Значение может быть установлено только один раз
- Запрет модификации: После инициализации свойство становится неизменяемым
- Работа с объектами: Для readonly-свойств объектного типа действуют особые правила
- Наследование: Readonly-свойства могут наследоваться с определёнными ограничениями
Базовый пример использования
class User {
public readonly int $id;
public readonly string $username;
public function __construct(int $id, string $username) {
// Инициализация в конструкторе
$this->id = $id;
$this->username = $username;
}
}
$user = new User(1, 'john_doe');
echo $user->id; // 1
echo $user->username; // john_doe
// Попытка изменить вызовет ошибку:
// $user->id = 2; // Fatal error: Uncaught Error: Cannot modify readonly property
Инициализация при объявлении
class Configuration {
public readonly string $environment = 'production';
public function __construct() {
// Можно не инициализировать в конструкторе,
// если значение задано при объявлении
}
}
Особенности работы с объектами
Для свойств объектного типа readonly предотвращает переназначение, но не модификацию внутреннего состояния объекта:
class Address {
public function __construct(public string $city) {}
}
class User {
public readonly Address $address;
public function __construct(Address $address) {
$this->address = $address;
}
}
$address = new Address('Moscow');
$user = new User($address);
// Это вызовет ошибку - нельзя переназначить свойство:
// $user->address = new Address('Saint Petersburg');
// Но можно изменить внутреннее состояние объекта:
$user->address->city = 'Saint Petersburg'; // Работает!
echo $user->address->city; // Saint Petersburg
Ограничения и правила
- Только для типизированных свойств: Readonly можно применять только к свойствам с явно указанным типом
- Нельзя применять к статическим свойствам:
public static readonly— недопустимо - Инициализация обязательна: Свойство должно быть инициализировано до окончания работы конструктора
- Неявная инициализация невозможна: Нельзя использовать методы, отличные от конструктора
Некорректный пример:
class Example {
public readonly int $value;
public function setValue(int $val) {
$this->value = $val; // Ошибка: нельзя инициализировать вне конструктора
}
}
Наследование readonly-свойств
class Base {
public readonly int $baseValue;
public function __construct(int $value) {
$this->baseValue = $value;
}
}
class Derived extends Base {
public readonly int $derivedValue;
public function __construct(int $baseVal, int $derivedVal) {
parent::__construct($baseVal);
$this->derivedValue = $derivedVal;
}
}
Практическое применение
DTO (Data Transfer Objects):
class UserDTO {
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly DateTimeImmutable $createdAt
) {}
}
// Иммутабельный объект для передачи данных
$user = new UserDTO(1, 'Alice', new DateTimeImmutable());
Конфигурационные объекты:
class AppConfig {
public function __construct(
public readonly string $databaseHost,
public readonly string $databaseName,
public readonly int $cacheTtl
) {}
}
Преимущества использования readonly
- Безопасность: Предотвращает случайное изменение важных данных
- Ясность кода: Чётко указывает на иммутабельность свойства
- Потокобезопасность: Readonly-объекты безопасны в многопоточных средах
- Предсказуемость: Гарантирует, что состояние объекта не изменится после создания
Отличия от const
Важно не путать readonly с константами:
- const: Значение должно быть известно на этапе компиляции, принадлежит классу
- readonly: Значение определяется в runtime, принадлежит экземпляру класса
class Example {
public const VERSION = '1.0'; // Константа класса
public readonly string $id; // Свойство экземпляра
}
Модификатор readonly значительно улучшает возможности создания иммутабельных объектов в PHP, что особенно важно для DTO, value-объектов и конфигурационных структур, обеспечивая лучшую предсказуемость и надёжность кода.