Свойства Readonly (PHP 8.1)
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 19 из 91.
В PHP 8.1 появились свойства readonly, которые могут быть назначены только один раз и не могут быть изменены впоследствии. В отличие от констант, свойства 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 обеспечивают неизменяемость на уровне свойств. Они идеально подходят для данных, которые идентифицируют объект или не должны меняться после создания, сочетая гибкость инициализации во время выполнения с безопасностью предотвращения случайных изменений.
Задание
ЛегкоДавайте создадим неизменяемую систему конфигурации, которая использует свойства 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 8.1 были представлены свойства 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; // U001
Свойства readonly должны иметь объявление типа и могут быть инициализированы только один раз. Они работают с любым модификатором видимости и могут сочетаться с продвижением свойств в конструкторе (constructor promotion):
<?php
class Product {
public function __construct(
public readonly string $sku,
private readonly float $cost
) {}
}
$product = new Product("ABC123", 29.99);
echo $product->sku; // ABC123
Свойства readonly идеально подходят для значений, которые должны оставаться неизменными на протяжении всего жизненного цикла объекта, таких как идентификаторы (ID), метки времени (timestamps) или параметры конфигурации.
Попробуйте сами
<?php
require_once 'Config.php';
// Чтение входных данных
$appName = trim(fgets(STDIN));
$version = trim(fgets(STDIN));
$maxConnections = intval(trim(fgets(STDIN)));
// TODO: Создайте объект Config, используя входные значения
// TODO: Выведите результат getInfo()
// TODO: Выведите каждое свойство только для чтения на отдельной строке:
// - название приложения
// - версия
// - максимальное количество подключений
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy