PHP的后期静态绑定

参考:https://blog.csdn.net/lamp_yang_3533/article/details/79912453

1.定义

后期静态绑定(也叫延迟静态绑定),可用于在继承范围内引用静态调用的类

2.工作原理

static 后期静态绑定的工作原理是存储了上一个非转发调用(non-forwarding call)的类名
  • 当进行静态方法调用时,该类名(static指向的类名)为明确指定的那个(通常是 :: 运算符的左侧部分),即实际调用时的类。
  • 当进行非静态方法调用时,即为该对象所属的类。
  • "后期绑定"的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。

3.转发调用

所谓的转发调用(forwarding call)指的是通过以下几种方式进行的静态调用:self::parent::static:: 以及 forward_static_call() 。

可用 get_called_class() 函数被调用的方法所在的类名。

 4.非转发调用

通过具体的类名或具体的对象进行的调用都是非转发调用,即非上面四种方式的调用都是非转发调用。

5.非静态环境下$this和static调用的区别

①$this 会优先寻找所在定义范围(父类)中的私有方法,如果存在就调用。
②static 是先到它指向的类(子类)中寻找私有方法,如果找到了就会报错,因为私有方法只能在它所定义的类内部调用;如果没找到,再去所在定义范围(父类)中寻找该私有方法,如果存在就调用。
<?php
 class  A  {
    private function  foo () {
        var_dump($this); echo '--';
        var_dump(new static); echo '--';
 
        echo __CLASS__; echo '--';
        echo get_called_class();
        echo '<br>';
    }
 
    public function  test () {
        $this -> foo ();
        static:: foo ();
        echo '<br>';
    }
}
 
class  B  extends  A  { }
 
class  C  extends  A  {
    private function foo () {
        echo 'this is C';
    }
}
 
(new  B())->test();
(new  C())->test();
?>

//输出结果
object(B)#1 (0) { } --object(B)#2 (0) { } --A--B
object(B)#1 (0) { } --object(B)#2 (0) { } --A--B

object(C)#1 (0) { } --object(C)#2 (0) { } --A--C
Fatal error: Uncaught Error: Call to private method C::foo() from context 'A' in /usercode/file.php:14 Stack trace: #0 /usercode/file.php(28): A->test() #1 {main} thrown in /usercode/file.php on line 14 
非静态环境下$this和static调用区别

6.后期静态绑定解析

后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。如果静态调用使用了 parent:: 或者 self:: 等转发调用的形式,将会转发调用信息。
<?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 ();
        static::foo();
        forward_static_call(['A', 'foo']);
        echo '<br>';
    }
 
    public static function  who () {
        echo  __CLASS__ . "\n" ;
    }
}
 
class  C  extends  B  {
    public static function  who () {
        echo  __CLASS__ . "\n" ;
    }
 
    public static function test2() {
        self::test();
    }
}
 
class  D  extends  C  {
    public static function  who () {
        echo  __CLASS__ . "\n" ;
    }
}
 
B::foo();
B::test();
 
C::foo();
C::test();
 
D::foo();
D::test2();
?>

//输出结果
B A B B B B 
C A C C C C 
D A D D D D 
后期静态绑定

 

posted @ 2018-11-30 19:01  zkeeper  阅读(151)  评论(0编辑  收藏  举报