PHP中的后期静态绑定

Posted wjf0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP中的后期静态绑定相关的知识,希望对你有一定的参考价值。

<?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();
        A::foo();
        B::foo();*/
        A::foo();
        parent::foo();
        self::foo();
    }

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

// 当有parent和self前缀时,可以考虑换成具体的类名进行思考
// 如果函数的内容是static前缀,则要考虑最后一次“非转发调用”的类名
// 当有parent和self前缀时,如此例,只需要考虑调用这个函数的类就可以了,在这里是C::test()
class C extends B {
public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

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

C::test();

// A C C
  • 转发调用: 进行静态调用时前面有static修饰的
  • 非转发调用: 直接通过类名,方法名调用的
  • 后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)中的类名
  • 意思是当我们调用一个转发调用的静态调用时,实际调用的类是上一个非转发调用的类。
  • 分析一下上面的例子
  • Class C的test方法中的三个方法,它们的非转发调用类都是C,因为它是直接通过C::test()方式访问的
    • A::foo() 非转发调用 方法内部又进行了转发调用,这时的上一个非转发调用的类是A,所以输出A
    • parent::foo() 调用了Class B的foo方法,该方法内进行了一次转发调用,这时的上一个非转发调用的类是C,所以输出C
    • self::foo() 调用了自身的foo方法,该方法内也进行了一次转发调用,道理同上,所以输出C
      • 可以尝试将Class C foo方法中的static::who()分别替换成self::who(), parent:who() 看看效果,前者输出C 后者输出B

以上是关于PHP中的后期静态绑定的主要内容,如果未能解决你的问题,请参考以下文章

单例中的 PHP 后期静态绑定

PHP中的后期静态绑定(Late Static Bindings )

PHP中的后期静态绑定

PHP 5.2 等效于后期静态绑定(新静态)?

PHP 后期静态绑定问题

PHP面向对象-后期静态绑定