为何相对静态调用未实现扩展类命名空间?为何仅static调用返回2?
关于PHP命名空间与静态调用的问题解答
咱们先把你的代码贴出来方便分析:
<?php namespace A { class B { static function test(){ echo 1; } static function check(){ B::test();//1 why? self::test();//1 static::test();//2 } } } namespace B { class B extends \A\B { static function test(){ echo 2; } } } namespace { B\B::check(); }
问题1:为何相对静态调用未实现扩展类的命名空间?
PHP里的相对类名解析是编译时确定的,不是运行时动态判断的。当在A\B类的check方法里写B::test()时,这个B会直接被解析成当前类所在命名空间下的A\B,和调用这个方法的子类B\B完全无关。
简单说,父类里的相对类名只会绑定到父类自己的命名空间,PHP在编译A\B类的时候,就已经把B::固定解析成\A\B::了,后续子类的命名空间不会影响这个解析结果。
问题2:为何仅static调用返回2?
这就要聊PHP的**后期静态绑定(Late Static Binding)**特性了,三个调用的核心区别如下:
self::test():self始终指向当前代码所在的类,也就是A\B,所以调用的是父类的test()方法,输出1。B::test():和问题1的逻辑一致,编译时就固定解析成\A\B::test(),输出1。static::test():static是后期静态绑定的关键字,它会指向实际运行时触发方法调用的类。这里我们是通过B\B::check()调用的,static就会动态绑定到子类B\B,自然调用的是子类重写的test()方法,输出2。
总结一下:相对类名的解析是编译时基于当前类的命名空间,而static是运行时动态绑定到实际调用的子类,这就是你看到不同输出的核心原因。
内容的提问来源于stack exchange,提问作者Алексей Винтер
相关产品推荐
相关产品推荐

