Комментарии к записи Новое в PHP 5.3.0: Позднее статическое связывание отключены
Поздним называется потому, что использование static:: будет означать вычисление класса/объекта, к которому будет относиться вызов, в момент вызова этой конструкции.
А статическим — потому что работает и для статических методов (но не только для них).
Для self:: и __CLASS__ всё по-старому — они ссылаются на класс, в котором определён метод.
Пример 1. Раннее связывание
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
classA{
publicstaticfunctionwho(){
echo__CLASS__;
}
publicstaticfunctiontest(){
self::who();
}
}
classBextendsA{
publicstaticfunctionwho(){
echo__CLASS__;
}
}
B::test();//вывод: A
?>
Использование позднего статического связывания
В отличие от предыдущего примера, использование позднего статического связывания (при помощи static::) позволяет попробовать обратиться к методу первоначально вызванного класса на этапе выполнения.
Таким образом, предыдущий пример превращается в:
Пример 2. Простой пример позднего статического связывания
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
classA{
publicstaticfunctionwho(){
echo__CLASS__;
}
publicstaticfunctiontest(){
static::who();// Here comes Late Static Bindings
}
}
classBextendsA{
publicstaticfunctionwho(){
echo__CLASS__;
}
}
B::test();//вывод: B
?>
Надо заметить, что static:: — не то же самое для класса, что и $this-> для объекта ($this-> следует правилам наследования, а static:: — нет).
Пример 3. Использование в нестатическом контексте
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
classTestChildextendsTestParent{
publicfunction__construct(){
static::who();
}
publicfunctiontest(){
$o=newTestParent();
}
publicstaticfunctionwho(){
echo__CLASS__."\n";
}
}
classTestParent{
publicfunction__construct(){
static::who();
}
publicstaticfunctionwho(){
echo__CLASS__."\n";
}
}
$o=newTestChild;//вывод: TestChild
$o->test();//вывод: TestParent
?>
Позднее статическое связывание не пойдёт выше, к предкам, а остановится на вызове метода инициировавшего его класса, тогда как self:: и parent:: будут всети себя согласно правилам наследования.
Пример 4. Переадресуемые и непереадресуемые вызовы