You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何相对静态调用未实现扩展类命名空间?为何仅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,提问作者Алексей Винтер

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:59:31