PHP中call_user_func结合parent调用的两类技术疑问
PHP静态方法调用中parent关键字的行为差异
以下是代码片段:
class A { static function bar() { echo get_called_class(), "\n"; } } class B extends A { static function foo() { call_user_func(['parent', 'bar']);// B 为何? call_user_func([parent::class, 'bar']); // A call_user_func(parent::class . '::bar');// A } }
问题解答
1. 为何call_user_func(['parent', 'bar'])的输出为B?
['parent', 'bar']这种调用方式里,parent是PHP的特殊关键字,它不会直接解析为父类的类名,而是保留了后期静态绑定的调用上下文。当在子类B的foo方法中使用该方式调用父类方法时,调用的实际上下文仍然是子类B,get_called_class()会返回触发调用的最终类(也就是B),而不是父类A。这是PHP为支持后期静态绑定,对parent关键字在动态调用场景下的特殊处理。
2. ['parent', 'bar']与[parent::class, 'bar']之间有何区别?
- 解析时机不同:
parent::class是编译时就确定的常量,会直接解析为父类的完全限定类名(这里就是A),所以[parent::class, 'bar']等价于['A', 'bar'];而['parent', 'bar']是运行时动态解析的,依赖当前代码的类上下文。 - 调用上下文不同:
[parent::class, 'bar']是直接以父类A的身份调用bar方法,此时get_called_class()返回A;而['parent', 'bar']保留了子类B的调用上下文,触发后期静态绑定行为,get_called_class()返回B。 - 本质差异:
parent::class是单纯的类名字符串,而parent在动态调用数组中是指向父类的动态引用,和当前类的继承关系实时绑定。
内容的提问来源于stack exchange,提问作者Z.XK
相关产品推荐
相关产品推荐

