Встречается на 20% собеседований по PHP

Что такое статическое связывание

Статическое связывание в PHP — это механизм, который позволяет определить, какой метод или свойство класса будет вызван, на основе класса, из которого происходит вызов, а не класса, в котором метод определён. В PHP это реализуется с помощью ключевого слова static и называется поздним статическим связыванием (late static binding). Оно особенно полезно при наследовании, когда нужно, чтобы вызов статического метода из родительского класса использовал переопределённую версию в дочернем классе.

Как это работает

В классическом наследовании, если родительский класс определяет статический метод, а дочерний его переопределяет, вызов этого метода через parent::method() или self::method() всегда будет ссылаться на метод родительского класса, даже если вызов происходит из контекста дочернего класса. Это происходит потому, что self привязывается к классу, где метод определён, а не к классу, из которого он вызван.

Позднее статическое связывание с ключевым словом static решает эту проблему: static::method() привязывается к классу, который был вызван в момент выполнения, то есть к фактическому классу, через который произошёл вызов. Это позволяет переопределённым методам дочерних классов корректно вызываться из унаследованного кода.

Пример

Рассмотрим классический пример с двумя классами:

php
class ParentClass {
    public static function who() {
        echo "Родительский класс\n";
    }

    public static function test() {
        static::who(); // Позднее статическое связывание
    }
}

class ChildClass extends ParentClass {
    public static function who() {
        echo "Дочерний класс\n";
    }
}

ParentClass::test(); // Вывод: Родительский класс
ChildClass::test(); // Вывод: Дочерний класс

В этом примере метод test() определён в ParentClass, но при вызове ChildClass::test() ключевое слово static заставляет PHP вызвать who() из ChildClass, потому что вызов происходит через ChildClass. Если бы использовалось self::who(), то в обоих случаях выводился бы «Родительский класс».

Подводные камни

  • Путаница с self: self всегда ссылается на класс, где метод определён, а static — на класс, из которого вызван. Это ключевое различие важно помнить.
  • Не путать с обычным статическим вызовом: Статическое связывание не означает, что решение принимается на этапе компиляции (как в некоторых других языках). В PHP это динамическое решение во время выполнения, но оно применяется только к статическим методам и свойствам.
  • Использование в нестатическом контексте: Позднее статическое связывание работает и для нестатических методов, но чаще применяется к статическим. В нестатическом контексте static также может быть полезен для переопределения.

Когда использовать

Позднее статическое связывание полезно при реализации паттернов проектирования, таких как фабрики, синглтоны, или когда требуется гибкое поведение в иерархии классов. Например, если базовый класс предоставляет общую логику, которая должна использовать переопределённые методы дочерних классов, static:: позволяет это сделать без дублирования кода.

Коротко

  • static::method() — позднее статическое связывание, привязка к классу, из которого вызван метод.
  • self::method() — привязка к классу, где метод определён.
  • Используется для корректного вызова переопределённых статических методов в наследовании.
  • Полезно в паттернах проектирования и при работе с иерархиями классов.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы