Объектно-ориентированное программирование на PHP
Освоение классов, объектов, свойств и методов, а также продвинутого объявления свойств в конструкторе (Constructor Property Promotion).
Основы ООП: Классы и Объекты
Для создания сложных систем, таких как интернет-магазин, процедурного подхода (просто функций и переменных) недостаточно. Здесь на помощь приходит Объектно-Ориентированное Программирование (ООП). Мы будем использовать метод Scaffolding (Скаффолдинг): начнем с базовой концепции класса, а затем постепенно усложним её, добавив современные фичи PHP 8.
Класс — это чертеж или шаблон. Например, чертеж товара. Объект — это конкретный экземпляр этого чертежа (например, конкретный ноутбук или телефон). Классы состоят из свойств (переменных, хранящих состояние объекта) и методов (функций, определяющих поведение объекта).
В ООП существует понятие инкапсуляции — сокрытия внутреннего состояния объекта от прямого изменения извне. Для этого используются модификаторы доступа:
- public — свойство или метод доступны отовсюду.
- protected — доступны внутри самого класса и его наследников.
- private — доступны только внутри самого класса.
При создании объекта вызывается специальный магический метод — конструктор (__construct). В старых версиях PHP программистам приходилось писать много шаблонного кода: объявлять свойства, передавать их в конструктор и затем присваивать значения. PHP 8 элегантно решил эту проблему.
| Синтаксис PHP 7 (Старый подход) | Синтаксис PHP 8 (Constructor Property Promotion) |
|---|---|
| class Product { public int $id; public function __construct(int $id) { $this->id = $id; } } | class Product { public function __construct( public int $id ) {} } |
Constructor Property Promotion в действии
Как видно из таблицы, Constructor Property Promotion позволяет объединить объявление свойства и его инициализацию прямо в параметрах конструктора. Это значительно сокращает объем кода и делает его более читаемым.
Давайте реализуем базовый класс Product для нашего интернет-магазина. Этот класс будет представлять товар в корзине. Мы типизируем свойства: id будет целым числом (int), name — строкой (string), а price — числом с плавающей точкой (float). Также мы добавим метод для форматирования цены, чтобы выводить её в интерфейсе с символом доллара и двумя знаками после запятой.
Обратите внимание на типизацию возвращаемого значения метода getFormattedPrice(): string. Это гарантирует, что метод всегда вернет строку, и защищает нас от ошибок при выводе данных в HTML-шаблоне.
<?php
// Практика: Класс Product (Архивный вариант 1, Упражнение 1.1)
class Product {
// Использование Constructor Property Promotion (PHP 8)
public function __construct(
public int $id,
public string $name,
public float $price
) {}
// Метод для получения отформатированной цены
public function getFormattedPrice(): string {
// number_format форматирует число с группировкой тысяч и знаками после запятой
return '$' . number_format($this->price, 2);
}
}
// Создание экземпляра (объекта) класса Product
$laptop = new Product(1, 'Apple MacBook Pro', 1999.99);
$mouse = new Product(2, 'Logitech Wireless Mouse', 25.50);
// Использование методов объекта
echo $laptop->name . " стоит " . $laptop->getFormattedPrice() . "<br>";
echo $mouse->name . " стоит " . $mouse->getFormattedPrice();
?>
Какую проблему решает Constructor Property Promotion в PHP 8?
Создание класса с продвинутым конструктором
Представьте, что вы разрабатываете модуль пользователей. Вам нужно создать класс User.
- Создайте класс User.
- Используя Constructor Property Promotion (PHP 8), добавьте в конструктор три public свойства: int $id, string $email, bool $isActive.
- Добавьте метод getStatus(): string, который возвращает 'Активен', если $isActive равен true, и 'Заблокирован', если false.