Геттеры и сеттеры
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 40 из 91.
Теперь, когда вы понимаете модификаторы доступа, как безопасно взаимодействовать с приватными свойствами извне класса? Ответ — геттеры и сеттеры — публичные методы, которые обеспечивают контролируемый доступ к приватным данным.
Геттер получает значение свойства, в то время как сеттер изменяет его. Этот паттерн позволяет добавить валидацию или логику при доступе к данным или их изменении:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
Вывод:
john@example.com
25Сеттер проверяет формат электронной почты и гарантирует корректность возраста перед сохранением значений. Без сеттеров любой мог бы напрямую присвоить некорректные данные. Вы также можете создавать свойства только для чтения, предоставляя только геттер, или свойства только для записи, используя только сеттер.
Ключевой момент: Геттеры и сеттеры дают вам контроль над тем, как осуществляется доступ к приватным данным и их изменение, позволяя выполнять валидацию, форматирование или любую пользовательскую логику.
Задание
ЛегкоДавайте создадим систему инвентаризации товаров, которая использует геттеры и сеттеры для защиты и валидации данных о товаре. Вы создадите класс Product, который гарантирует, что цены всегда положительны, а количество на складе никогда не бывает отрицательным — демонстрируя, как сеттеры могут обеспечивать соблюдение бизнес-правил.
Вы организуете свой код в двух файлах:
Product.php— Создайте классProductс тремя приватными свойствами:$name(string),$price(float) и$stock(integer). Реализуйте геттеры и сеттеры для каждого свойства со следующими правилами валидации:setName()должен принимать только непустые строки — если после обрезки пробелов (trimming) строка пуста, не обновляйте свойствоsetPrice()должен принимать только значения больше 0 — отклоняйте нулевые или отрицательные ценыsetStock()должен принимать только значения 0 или больше — отклоняйте отрицательное количество товара
getInfo(), который возвращает"[name]: $[price] ([stock] in stock)"с ценой, отформатированной до 2 знаков после запятой.main.php— Подключите файл Product. Вы получите четыре входных значения: название товара, цену, количество на складе и новую цену для обновления. Создайте экземплярProductи используйте сеттеры для присвоения начального имени, цены (преобразованной в float) и количества (преобразованного в integer). Выведите результат работыgetInfo(). Затем попробуйте обновить цену новым значением цены (преобразованным в float) и снова выведитеgetInfo(). Наконец, попробуйте установить количество на складе в-5(недопустимое значение) и выведитеgetInfo()еще раз, чтобы подтвердить, что количество не изменилось.
Ваши сеттеры действуют как привратники — они проверяют входящие данные перед тем, как разрешить изменения приватных свойств. Когда передаются недопустимые данные (например, отрицательное количество на складе), сеттер просто игнорирует их, сохраняя существующее допустимое значение нетронутым. В этом заключается сила инкапсуляции: ваш объект сохраняет свою целостность независимо от того, что пытается сделать внешний код.
Попробуйте сами
<?php
require_once 'Product.php';
// Чтение входных данных
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: Создайте новый экземпляр Product
// TODO: Используйте сеттеры для назначения начального name, price (как float) и stock (как integer)
// TODO: Выведите результат getInfo()
// TODO: Обновите цену с помощью newPrice (как float) и снова выведите getInfo()
// TODO: Попробуйте установить stock в -5 (недопустимое значение) и выведите getInfo(), чтобы подтвердить, что stock не изменился
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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