Геттеры и сеттеры
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 40 из 91.
Теперь, когда вы понимаете модификаторы доступа, как безопасно взаимодействовать с private-свойствами из-за пределов класса? Ответ — getters and setters — public-методы, которые обеспечивают контролируемый доступ к private-данным.
getter получает значение свойства, а сеттер изменяет его. Этот шаблон позволяет добавлять проверку или логику при доступе к данным или их изменении:
<?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Сеттер проверяет формат email и убеждается, что age имеет разумное значение, прежде чем сохранить эти значения. Без сеттеров любой мог бы напрямую присвоить недопустимые данные. Вы также можете создать свойства только для чтения, предоставив лишь getter, или свойства только для записи, используя лишь сеттер.
Ключевой момент: getter и сеттеры дают вам контроль над тем, как осуществляется доступ к private данным и их изменение, позволяя выполнять проверку, форматирование или любую пользовательскую логику.
Задание
ЛегкоДавайте создадим систему учёта товаров, которая использует геттеры и сеттеры для защиты и проверки данных о товарах. Вы создадите класс Product, который гарантирует, что цены всегда положительны, а количества на складе никогда не отрицательны: это демонстрирует, как сеттеры могут обеспечивать соблюдение бизнес-правил.
Вы организуете код в двух файлах:
Product.php: Создайте классProductс тремя private-свойствами:$name(строка),$price(float) и$stock(integer). Implement геттеры и сеттеры для каждого свойства со следующими правилами проверки:setName()должен accept только непустые строки; если строка пуста после удаления пробелов, не изменяйте свойствоsetPrice()должен accept только значения, greater 0: отклоняйте нулевые и отрицательные ценыsetStock()должен accept только значения 0 или greater: отклоняйте отрицательные количества на складе
getInfo(), который возвращает"[name]: $[price] ([stock] in stock)", при этом цена должна быть отформатирована с точностью до 2 десятичных разрядов.main.php: Подключите файл Product. Вы получите четыре входных значения: название товара, цену, количество на складе и новую цену для обновления. Создайте экземплярProductи используйте сеттеры, чтобы assign initial имя, цену (преобразованную в float) и количество на складе (преобразованное в integer). Print результатgetInfo(). Затем попытайтесь обновить цену новым значением (преобразованным в float) и снова выведитеgetInfo(). Наконец, попытайтесь установить количество на складе равным-5(invalid значение) и ещё раз выведитеgetInfo(), чтобы confirm, что количество на складе не изменилось.
Ваши сеттеры действуют как привратники. Они проверяют входящие данные перед тем, как разрешить изменения private-свойств. Когда передаются недопустимые данные (например, отрицательное количество на складе), сеттер просто игнорирует их, сохраняя существующее корректное значение. В этом заключается сила инкапсуляции: ваш объект сохраняет свою целостность независимо от того, что пытается сделать внешний код.
Попробуйте сами
<?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: Обновить price значением newPrice (как float) и снова вывести getInfo()
// TODO: Попытаться установить stock равным -5 (недопустимо) и вывести getInfo(), чтобы подтвердить, что stock не изменился
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов2Пространства имён и автозагрузка
Введение в пространства имёнКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerПовторение — структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс и абстрактный классАннотация типов с интерфейсамиПовторение — калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeПовторение — пользовательская коллекция3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищённые свойстваСвойства только для чтения (PHP 8.1)Повторение — менеджер банковского счёта6Полиморфизм
Повторение переопределения методовПолиморфизм через интерфейсыАннотации типов и объединённые типыПозднее статическое связываниеПовторение — обработчик платежей9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования, часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн StrategyПотренируйтесь самостоятельно: Онлайн-компилятор PHP