Constructor Promotion (8.0)
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 42 из 91.
В PHP 8.0 появилось продвижение свойств в конструкторе (constructor promotion) — функция, которая значительно сокращает объем шаблонного кода при определении классов. Вместо того чтобы объявлять свойства отдельно, а затем присваивать им значения в конструкторе, вы можете сделать и то, и другое за один шаг.
Вот традиционный подход, который вы использовали:
<?php
class Product {
private string $name;
private float $price;
public function __construct(string $name, float $price) {
$this->name = $name;
$this->price = $price;
}
public function getInfo(): string {
return $this->name . ": $" . $this->price;
}
}
С продвижением свойств в конструкторе (constructor promotion) вы добавляете модификатор доступа непосредственно к параметрам конструктора:
<?php
class Product {
public function __construct(
private string $name,
private float $price
) {}
public function getInfo(): string {
return $this->name . ": $" . $this->price;
}
}
$product = new Product("Laptop", 999.99);
echo $product->getInfo();
Вывод:
Laptop: $999.99Добавляя private, protected или public перед параметром конструктора, PHP автоматически создает свойство и присваивает ему значение. Вы можете смешивать продвигаемые и обычные параметры в одном и том же конструкторе, и вы все равно можете добавить логику внутрь тела конструктора, если это необходимо.
Ключевой момент: Продвижение свойств в конструкторе устраняет повторяющиеся объявления и присваивания свойств, делая ваши классы чище и легче для чтения, сохраняя при этом полный контроль над инкапсуляцией.
Задание
ЛегкоДавайте создадим систему управления контактами, которая демонстрирует элегантность продвижения свойств в конструкторе (constructor promotion). Вы создадите чистый, современный PHP-класс, который устраняет шаблонный код, сохраняя при этом правильную инкапсуляцию.
Вы организуете свой код в двух файлах:
Contact.php— Создайте классContact, используя продвижение свойств в конструкторе для определения всех свойств непосредственно в сигнатуре конструктора. Ваш контакт должен иметь:- Приватное свойство
$name(string) - Приватное свойство
$email(string) - Приватное свойство
$phone(string) со значением по умолчанию"Not provided"
getFullDetails(), который возвращает"[name] | [email] | [phone]". Также добавьте методgetSummary(), который возвращает"Contact: [name]".- Приватное свойство
main.php— Подключите файл Contact. Вы получите три входных значения: имя, email и номер телефона. Создайте два экземпляраContact:- Первый контакт должен использовать все три значения (имя, email и телефон)
- Второй контакт должен использовать только имя и email (полагаясь на значение телефона по умолчанию)
- Полные сведения о первом контакте
- Краткую сводку о первом контакте
- Полные сведения о втором контакте
- Краткую сводку о втором контакте
Обратите внимание, как продвижение свойств в конструкторе позволяет определять свойства, устанавливать их видимость, объявлять их типы и присваивать значения — и все это в одной читаемой сигнатуре конструктора. Необязательный параметр телефона со значением по умолчанию демонстрирует, что продвигаемые параметры бесшовно работают со значениями по умолчанию, точно так же, как и обычные параметры.
Шпаргалка
PHP 8.0 представил продвижение свойств в конструкторе (constructor promotion), которое позволяет объявлять и инициализировать свойства класса непосредственно в параметрах конструктора, добавляя модификатор доступа.
Традиционный подход:
<?php
class Product {
private string $name;
private float $price;
public function __construct(string $name, float $price) {
$this->name = $name;
$this->price = $price;
}
}
С использованием продвижения свойств в конструкторе:
<?php
class Product {
public function __construct(
private string $name,
private float $price
) {}
}
$product = new Product("Laptop", 999.99);
Добавляя private, protected или public перед параметром конструктора, PHP автоматически создает свойство и присваивает ему значение.
Вы можете использовать значения по умолчанию для продвигаемых параметров:
<?php
class Contact {
public function __construct(
private string $name,
private string $email,
private string $phone = "Not provided"
) {}
}
Продвижение свойств в конструкторе можно смешивать с обычными параметрами, и вы по-прежнему можете добавлять логику внутрь тела конструктора, если это необходимо.
Попробуйте сами
<?php
require_once 'Contact.php';
// Чтение входных данных
$name = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));
// TODO: Создать первый контакт со всеми тремя значениями (имя, email, телефон)
// TODO: Создать второй контакт только с именем и email (использовать телефон по умолчанию)
// TODO: Вывести полную информацию о первом контакте
// TODO: Вывести краткую информацию о первом контакте
// TODO: Вывести полную информацию о втором контакте
// 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