В PHP есть такая фича, как позднее статическое связывание (late static binding или LSB). Она позволяет обратиться к вызываемому/инстанциированному классу в контексте наследования.
Когда-то давно для работы с LSB использовались функции forward_static_call, forward_static_call_array, get_called_class. Теперь всё это можно делать через
static:
/**
* @psalm-consistent-constructor
* @phpstan-consistent-constructor
*/
class A
{
final public static function staticClass(): string
{
return static::class;
}
final public static function newStatic(): static
{
return new static();
}
}
class B extends A {}
var_dump(
A::staticClass(), // "A"
A::newStatic(), // object(A)
A::newStatic()::staticClass(), // "A"
B::staticClass(), // "B"
B::newStatic(), // object(B)
B::newStatic()::staticClass(), // "B"
);
Обратимся к документации, чтобы разобраться в нейминге. Почему связывание "позднее"?
Природа названия «позднее статическое связывание» возникает из внутренней логики работы языка. Связывание называется «поздним», потому что конструкция static:: разрешается не в тот класс, в котором определили метод, а вычисляется на основе информации в ходе исполнения программы.Ок, это понятно. Но почему "статическое" и почему
static?Связывание также назвали «статическим», поскольку этот механизм в числе прочего умеет вызывать статические методы.
А вот тут не логично, согласитесь.
static — это про то, что метод/свойство доступны без объекта, а не про то, на какой класс мы ссылаемся. Гораздо лучше было бы взять called:: или late::. Документация объясняет, почему так вышло:Вместо введения нового ключевого слова для позднего статического связывания разработчики языка выбрали ключевое слово static, которое зарезервировали прежде.Тем не менее, мы с вами так привыкли к
static, что уже не чувствуем нелогичности этого нейминга...