Menu
Coddy logo textTech

Свойства Readonly (PHP 8.1)

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 19 из 91.

В PHP 8.1 появились свойства readonly, которые могут быть назначены только один раз и не могут быть изменены впоследствии. В отличие от констант, свойства readonly устанавливаются во время инициализации объекта, а не во время определения класса.

Вы объявляете свойство только для чтения, добавляя ключевое слово readonly перед объявлением типа:

<?php
class User {
    public readonly string $id;
    public readonly string $name;
    
    public function __construct(string $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

$user = new User("U001", "Alice");
echo $user->id . "\n";
echo $user->name;

Вывод:

U001
Alice

После присвоения попытка изменить свойство readonly приведет к ошибке. Это делает их идеальными для значений, которые должны оставаться неизменными на протяжении всего жизненного цикла объекта, таких как ID или метки времени создания.

Свойства readonly должны иметь объявление типа и могут быть назначены только один раз, внутри объявляющего класса (обычно в конструкторе). В отличие от обычных свойств, им нельзя присвоить значение по умолчанию при объявлении. Они работают с любым модификатором видимости:

<?php
class Product {
    public function __construct(
        public readonly string $sku,
        private readonly float $cost
    ) {}
    
    public function getCost(): float {
        return $this->cost;
    }
}

$product = new Product("ABC123", 29.99);
echo $product->sku;

Вывод:

ABC123

Ключевой момент: Свойства только для чтения (readonly) обеспечивают неизменяемость на уровне свойств. Они идеально подходят для данных, которые идентифицируют объект или не должны меняться после создания, сочетая гибкость инициализации во время выполнения с безопасностью предотвращения случайных изменений.

challenge icon

Задание

Легко

Давайте создадим неизменяемую систему конфигурации, которая использует свойства readonly, чтобы гарантировать, что критически важные настройки не могут быть случайно изменены после инициализации.

Вы создадите два файла, которые работают вместе для управления конфигурацией приложения:

  • Config.php — Определите класс Config, который представляет конфигурацию приложения с неизменяемыми настройками. Класс должен иметь три публичных свойства readonly: string $appName, string $version и int $maxConnections. Используйте продвижение параметров конструктора (constructor promotion), чтобы объявить и инициализировать все три свойства readonly в одном лаконичном определении конструктора. Добавьте метод getInfo(), который возвращает строку в формате "[appName] v[version] (max: [maxConnections] connections)".
  • main.php — Подключите файл класса Config. Вы получите три входных значения: название приложения, версию и максимальное количество соединений (в виде строки, которую необходимо преобразовать в целое число). Создайте объект Config, используя эти значения. Выведите результат работы getInfo() на первой строке. Затем выведите каждое свойство readonly на отдельной строке, обращаясь к ним напрямую: название приложения, версию и максимальное количество соединений.

Свойства readonly гарантируют, что после создания конфигурации ее значения фиксируются — это идеально подходит для настроек, которые должны оставаться неизменными на протяжении всего времени работы вашего приложения. Обратите внимание, как продвижение параметров конструктора в сочетании с readonly позволяет очень кратко определять неизменяемые объекты-значения (value objects).

Ваш вывод должен отображать отформатированную информационную строку, за которой следует каждое отдельное значение свойства, демонстрируя, что свойства readonly все еще могут быть прочитаны извне класса.

Попробуйте сами

<?php

require_once 'Config.php';

// Чтение входных данных
$appName = trim(fgets(STDIN));
$version = trim(fgets(STDIN));
$maxConnections = intval(trim(fgets(STDIN)));

// TODO: Создайте объект Config, используя входные значения

// TODO: Выведите результат getInfo()

// TODO: Выведите каждое свойство readonly на отдельной строке:
// - название приложения
// - версия
// - максимальное количество подключений

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование