后期静态绑定解读

后期静态绑定解读

先看下官网的这段代码
[官方解释][1]
下面摘自官网

后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 parent:: 或者 self:: 将转发调用信息。
准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。可用 get_called_class() 函数来得到被调用的方法所在的类名,static:: 则指出了其范围。

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
28
29
30
31
<?php
class A {
public static function foo() {
static::who();
}

public static function who() {
echo __CLASS__."\n";
}
}

class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}

public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}

C::test();
//A C C
?>

这里C::test() 调用执行到B下的test()
然后依次执行
A::foo() parent::foo() self::foo()
A::foo()直接看成是A自己执行自己的方法,所以他调用自己的static::who() 这边进来没用到转发调用 直接输出A
parent::foo() 进入A下的foo 里面是后期静态绑定的who ,这里执行的上一次非转发调用官网所说的上一个“非转发调用”(non-forwarding call)的类名。

后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名

很明显这里的static这的类名不是B下的因为B是转发调用,B的上一层就是C,C下有who方法因此就执行这里的who,打印C。
同理,self也是,打印的也是C。

我们把上面的这段代码改一下

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
28
29
30
31
32

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
class D extends C {
public static function who() {
echo __CLASS__."\n";
}
}
D::test();
//A D D

这时候结果不再是 A C C 而是 A D D ,也就是说这里的static 绑定到了D,而非C。
同理

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
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {

}
class D extends C {

}
D::test();
//A B B

如果我们只留下A下的foo()

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
<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}

}
class C extends B {

}
class D extends C {

}
D::test();
// A A A

也就这里没有静态绑定成功 直接用的就是A类下的who()
现在就很明显了当我们调用一个static::function() (静态绑定方法)他会把这个方法绑定到在继承关系中存在这个方法的最年轻的类中的方法。
[1]: http://www.golaravel.com/php/language.oop5.late-static-bindings.html

新家

由于阿里云太坑了,原本想一直用着阿里的那个学生服务器,可是后来阿里强行要求签到10天才能发抵用券,我索性就放弃治疗了。还好,腾讯还算厚道,我那个测试论坛现在还跑在腾讯的服务器上,每个月只是象征性地收一块钱,速度还比阿里的签到10天还要10快的服务器好多了。

从同事那听说 他有用github page 效果还蛮好,关键是我再也不用担心服务器续费问题了,这里以后就是记录我程序员生涯的地方了,蛮好。😊

这里主要还是写点PHP,C,数据结构,设计模式这类东西,希望对自己有点作用。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×