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
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(); // john@example.com
echo $user->getAge(); // 25

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

Попробуйте сами

<?php
require_once 'Product.php';

// Чтение входных данных
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));

// TODO: Создать новый экземпляр Product

// TODO: Использовать сеттеры для назначения начального имени, цены (как float) и остатка (как integer)

// TODO: Вывести результат getInfo()

// TODO: Обновить цену на newPrice (как float) и снова вывести getInfo()

// TODO: Попытаться установить остаток на -5 (недопустимо) и вывести getInfo(), чтобы подтвердить, что остаток не изменился

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

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

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