← Назад к вопросам

Что такое модификатор чтения свойства?

2.0 Middle🔥 171 комментариев
#Другое

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое модификатор чтения свойства?

В PHP 8.1 была представлена новая функциональность — модификатор readonly для свойств. Это модификатор доступа, который позволяет объявлять свойства класса как неизменяемые после инициализации. То есть, свойство может получить значение только один раз — при создании объекта (в конструкторе или при объявлении), и далее это значение нельзя изменить извне или из методов класса.

Основные характеристики readonly-свойств:

1. Однократная инициализация:
Значение может быть присвоено только один раз — в момент объявления или в конструкторе класса.

2. Защита от модификации:
После инициализации любая попытка изменения свойства приведёт к фатальной ошибке.

3. Применяется только к свойствам:
Модификатор работает исключительно со свойствами класса, но не с методами или аргументами функций.

Синтаксис и примеры

Базовый синтаксис:

class Product 
{
    public readonly string $id;
    public readonly string $name;
    
    public function __construct(string $id, string $name) 
    {
        $this->id = $id;   // Разрешено — инициализация в конструкторе
        $this->name = $name;
    }
}

$product = new Product('p123', 'Laptop');
echo $product->name; // Выведет: Laptop

// $product->name = 'Tablet'; // Ошибка! Нельзя изменить readonly-свойство

Инициализация при объявлении (PHP 8.2+):

class Configuration 
{
    public readonly string $environment = 'production'; // Разрешено
}

Ключевые правила использования:

  • Типизация обязательна: Readonly-свойство всегда должно иметь явно указанный тип (например, string, int, DateTime и т.д.).
  • Нельзя объявить static readonly: Свойство не может быть одновременно статическим и только для чтения.
  • Инициализация: Допускается инициализация в конструкторе ИЛИ при объявлении, но не в других методах класса.
  • Наследование: Readonly-свойства наследуются, но дочерний класс не может изменить модификатор родительского свойства.

Практический пример с валидацией:

class User 
{
    public readonly int $id;
    public readonly string $email;
    
    public function __construct(int $id, string $email) 
    {
        // Можно добавить валидацию при инициализации
        if ($id <= 0) {
            throw new InvalidArgumentException('ID must be positive');
        }
        
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('Invalid email address');
        }
        
        $this->id = $id;
        $this->email = $email;
    }
}

$user = new User(1, 'test@example.com');
// $user->id = 2; // Вызовет Fatal error: Cannot modify readonly property

Отличия от других подходов:

Сравнение с геттерами:

// Старый подход с геттерами
class OldWay 
{
    private string $name;
    
    public function __construct(string $name) {
        $this->name = $name;
    }
    
    public function getName(): string {
        return $this->name;
    }
}

// Новый подход с readonly
class NewWay 
{
    public readonly string $name;
    
    public function __construct(string $name) {
        $this->name = $name;
    }
    // Геттер не нужен — свойство публичное, но защищённое от изменений
}

Сравнение с const:
В отличие от констант класса (const), readonly-свойства:

  • Могут иметь разные значения для разных экземпляров объекта
  • Могут быть нестатическими
  • Их значение устанавливается во время выполнения, а не компиляции

Преимущества использования:

  1. Безопасность данных: Гарантирует, что важные свойства объекта не будут случайно изменены
  2. Упрощение кода: Убирает необходимость в boilerplate-коде с геттерами и валидацией
  3. Повышение читаемости: Явно указывает намерение разработчика — свойство должно быть неизменяемым
  4. Потокобезопасность: Неизменяемые объекты безопаснее в многопоточных средах

Ограничения и нюансы:

  • Глубокая неизменяемость: Readonly гарантирует неизменяемость только ссылки на объект, но не внутреннего состояния объектов:
class Container 
{
    public readonly array $items;
    
    public function __construct() {
        $this->items = [1, 2, 3];
    }
}

$container = new Container();
// $container->items = [4, 5, 6]; // Ошибка!
$container->items[] = 4; // Разрешено! Массив изменяется
  • Клонирование: При клонировании объекта readonly-свойства можно повторно инициализировать:
$user1 = new User(1, 'test@example.com');
$user2 = clone $user1;
// $user2 — новый объект, его свойства можно установить через конструктор

Заключение

Модификатор readonly — это мощное средство для создания иммутабельных (неизменяемых) объектов и значимых объектов (value objects) в PHP. Он позволяет писать более безопасный, чистый и поддерживаемый код, явно выражая архитектурные решения на уровне синтаксиса языка. При проектировании классов, особенно DTO (Data Transfer Objects), сущностей предметной области и конфигурационных объектов, использование readonly свойств значительно снижает риск случайных ошибок и делает контракты классов более явными.