Сработает ли магический метод __set() при присвоении значения свойству класса?

«Сработает ли магический метод __set() при присвоении значения свойству класса?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, метод __set() будет вызван автоматически при попытке присвоить значение недоступному или несуществующему свойству объекта.

Условия срабатывания:

  1. Свойство объявлено как private или protected.
  2. Свойство не существует в классе.
  3. Вызов происходит в контексте объекта (не статически).

Пример:

class UserSettings {
    private array $storage = [];

    public function __set(string $name, mixed $value): void {
        // Логируем или валидируем перед записью
        if ($name === 'email' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('Invalid email');
        }
        $this->storage[$name] = $value;
    }

    public function __get(string $name): mixed {
        return $this->storage[$name] ?? null;
    }
}

$settings = new UserSettings();
$settings->email = 'user@example.com'; // Вызовет __set()
$settings->theme = 'dark'; // Также вызовет __set()
echo $settings->email; // Вызовет __get()

Важные нюансы:

  • Для public-свойств __set() не вызывается.
  • Метод должен быть объявлен как public.
  • Часто используется для:
    • Реализации динамических свойств (как в примере выше).
    • Валидации данных перед записью.
    • Логирования изменений свойств.
    • Проксирования запросов к внешнему хранилищу.
  • В отличие от __get(), который может вызываться и при чтении, __set() работает только на запись.