Menu
Coddy logo textTech

Геттеры и сеттеры

Часть раздела Объектно-ориентированное программирование путешествия по 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

Сеттер проверяет формат электронной почты и гарантирует корректность возраста перед сохранением значений. Без сеттеров любой мог бы напрямую присвоить некорректные данные. Вы также можете создавать свойства только для чтения, предоставляя только геттер, или свойства только для записи, используя только сеттер.

Ключевой момент: Геттеры и сеттеры дают вам контроль над тем, как осуществляется доступ к приватным данным и их изменение, позволяя выполнять валидацию, форматирование или любую пользовательскую логику.

challenge icon

Задание

Легко

Давайте создадим систему инвентаризации товаров, которая использует геттеры и сеттеры для защиты и валидации данных о товаре. Вы создадите класс 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 не изменился

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование