Menu
Coddy logo textTech

__get, __set, __isset, __unset

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 46 из 91.

PHP предоставляет четыре магических метода, которые перехватывают доступ к свойствам: __get(), __set(), __isset() и __unset(). Они срабатывают, когда вы пытаетесь получить доступ к свойствам, которые не существуют или недоступны.

Метод __get() вызывается при чтении недоступного свойства, в то время как __set() обрабатывает запись в него. Это позволяет создавать динамические свойства или добавлять логику при обращении к свойствам:

<?php
class DynamicObject {
    private array $data = [];
    
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
}

$obj = new DynamicObject();
$obj->title = "Hello";
$obj->count = 42;
echo $obj->title . " - " . $obj->count;

Вывод:

Hello - 42

Метод __isset() вызывается при использовании isset() или empty(), а __unset() реагирует на функцию unset():

<?php
class DynamicObject {
    private array $data = [];
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
    
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }
    
    public function __unset(string $name): void {
        unset($this->data[$name]);
    }
}

$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing";

Вывод:

exists

Эти методы обычно используются для создания гибких контейнеров данных, реализации ленивой загрузки или создания объектов, которые ведут себя как массивы, сохраняя при этом объектно-ориентированную структуру.

challenge icon

Задание

Легко

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

Вы организуете свой код в двух файлах:

  • Config.php — Создайте класс Config, который использует приватный массив для внутреннего хранения значений конфигурации. Реализуйте все четыре магических метода для работы со свойствами:
    • __get($name) — Возвращает значение для данного ключа или "undefined", если ключ не существует
    • __set($name, $value) — Сохраняет значение под данным ключом
    • __isset($name) — Возвращает, существует ли ключ в конфигурации
    • __unset($name) — Удаляет ключ из конфигурации
    Также добавьте метод count(), который возвращает количество сохраненных настроек.
  • main.php — Подключите файл Config. Вы получите три входных значения: имя настройки, значение настройки и второе имя настройки. Создайте экземпляр Config и выполните следующие операции:
    • Установите первую настройку в заданное значение
    • Выведите, существует ли первая настройка, используя isset() — выведите "exists" или "missing"
    • Выведите значение первой настройки
    • Выведите текущее количество настроек
    • Используйте unset(), чтобы удалить первую настройку
    • Выведите, существует ли первая настройка теперь — выведите "exists" или "missing"
    • Выведите значение второй настройки (которая никогда не была установлена)

Каждый вывод должен быть на отдельной строке. Магические методы позволяют вам взаимодействовать с объектом Config, используя естественный синтаксис свойств, такой как $config->theme = "dark" и isset($config->theme), даже если фактические свойства не определены.

Шпаргалка

PHP предоставляет четыре магических метода для перехвата доступа к свойствам:

  • __get(string $name): mixed — вызывается при чтении недоступного свойства
  • __set(string $name, mixed $value): void — вызывается при записи в недоступное свойство
  • __isset(string $name): bool — срабатывает при использовании isset() или empty()
  • __unset(string $name): void — срабатывает при использовании unset()

Пример использования __get() и __set():

<?php
class DynamicObject {
    private array $data = [];
    
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
}

$obj = new DynamicObject();
$obj->title = "Hello";
echo $obj->title; // Hello

Пример использования __isset() и __unset():

<?php
class DynamicObject {
    private array $data = [];
    
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }
    
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }
    
    public function __unset(string $name): void {
        unset($this->data[$name]);
    }
}

$obj = new DynamicObject();
$obj->name = "Test";
echo isset($obj->name) ? "exists" : "missing"; // exists

Эти методы позволяют реализовать динамические свойства, ленивую загрузку и гибкие контейнеры данных, сохраняя при этом объектно-ориентированную структуру.

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

<?php

require_once 'Config.php';

// Чтение входных данных
$settingName1 = trim(fgets(STDIN));
$settingValue = trim(fgets(STDIN));
$settingName2 = trim(fgets(STDIN));

// TODO: Создать экземпляр Config

// TODO: Установить первую настройку в заданное значение

// TODO: Вывести, существует ли первая настройка ("exists" или "missing")

// TODO: Вывести значение первой настройки

// TODO: Вывести текущее количество настроек

// TODO: Использовать unset() для удаления первой настройки

// TODO: Вывести, существует ли первая настройка сейчас ("exists" или "missing")

// TODO: Вывести значение второй настройки (которая никогда не была установлена)

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

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

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