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

Ответ

Позднее статическое связывание (Late Static Binding) в PHP позволяет вызывать статические методы и свойства класса с учетом контекста выполнения, а не только объявления.

Ключевое слово static используется вместо self, чтобы обращаться к классу, который был вызван в рантайме, а не к тому, где метод объявлен.

Пример:

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Позднее связывание
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // Выведет "B" (а не "A" как было бы с self)

Используется для:

  • Переопределения статических методов в наследниках
  • Реализации паттернов типа Singleton с наследованием
  • Гибкости при работе с иерархией классов

Ответ 18+ 🔞

А, слушай, про эту вашу позднюю статическую привязку в PHP! Ну это ж классика, блядь, ёпта! Ситуация, когда ты думаешь, что вызываешь метод родителя, а на самом деле тебе подсовывают какого-то хитрожопого наследника.

Представь, есть у тебя класс A, и в нём статический метод test(). И внутри этого метода он зовёт другого себя — self::who(). И всё бы ничего, но если ты наследуешь от него класс B и переопределяешь этот who(), то при вызове B::test() тебя всё равно по старой памяти потащит в A::who(). Потому что self — это как клеймо на жопе, блядь, привязанное к месту объявления. И тут ты такой: «Да что ж это за хуйня?»

А вот тут-то и выходит на сцену наш спаситель — ключевое слово static вместо self. Это как будто ты говоришь: «Эй, а кто тут у нас на самом деле вызвал этот метод? А, это ты, Б? Ну так давай, сука, работай по-своему!»

Вот смотри, на примере, тут всё ясно как божий день:

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Вот эта строчка — вся магия, блядь!
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // Выведет "B"

Видишь? Раньше бы с self::who() нарисовалась бы «А», а тут — «B». Потому что static — это не про «где написали», а про «кто реально позвал» в рантайме. Вообще, волнение ебать, когда осознаёшь эту разницу!

А нахуя это вообще нужно, спросишь? Да обычное дело:

  • Когда ты пишешь библиотеку, а какой-нибудь полупидор её наследует и хочет, чтобы твой статический метод фабрики создавал его объекты, а не твои.
  • Паттерн типа Singleton, чтобы каждый наследник был сам себе единственным экземпляром, а не все на одном родительском висели.
  • Ну и вообще для любой гибкости, когда у тебя иерархия классов и статика. Без этого — просто пиздец и боль, чувак.

Короче, static:: — это как сказать: «Работай не по понятиям объявления, а по понятиям вызова, блядь». Иногда без этого — нихуя не обойтись.