我最近阅读过在PHP中调用范围和范围解析运算符(::)。有两种变体:实例调用和静态调用。考虑下面的听法:
<?php
class A {
public function __call($method, $parameters) {
echo "I'm the __call() magic method".PHP_EOL;
}
public static function __callStatic($method, $parameters) {
echo "I'm the __callStatic() magic method".PHP_EOL;
}
}
class B extends A {
public function bar() {
A::foo();
}
}
class C {
public function bar() {
A::foo();
}
}
A::foo();
(new A)->foo();
B::bar();
(new B)->bar();
C::bar();
(new C)->bar();
执行结果(PHP 5.4.9-4ubuntu2.2)是:
I'm the __callStatic() magic method
I'm the __call() magic method
I'm the __callStatic() magic method
I'm the __call() magic method
I'm the __callStatic() magic method
I'm the __callStatic() magic method
我不明白为什么(new C)->bar();
执行__callStatic()
的{{1}}?实例调用应该在bar()方法的上下文中进行,不是吗?是PHP的功能吗?
Addition1:
此外,如果我不使用魔术方法并明确调用,一切都按预期工作:
A
结果:
<?php
class A {
public function foo() {
echo "I'm the foo() method of A class".PHP_EOL;
echo 'Current class of $this is '.get_class($this).PHP_EOL;
echo 'Called class is '.get_called_class().PHP_EOL;
}
}
class B {
public function bar() {
A::foo();
}
}
(new B)->bar();
答案 0 :(得分:3)
在bar()
的{{1}}方法中,您有C
:
A::foo();
由于此方法既未创建public function bar() {
A::foo();
}
的实例,也未A
扩展C
,因此A
运算符被视为试图调用的静态运算符静态方法::
。由于A::foo()
未定义foo()
,因此它会回落到A
方法。
如果您希望它在不延长__callStatic()
的情况下调用非静态方法,则必须创建A
的实例:
A
答案 1 :(得分:0)
这是因为在这种情况下我们没有A
类的实例。
注意
class B extends A
因此,new B
可让我们访问{静态版A->foo
。
类C
不会扩展A
,因此只有A
的静态方法可用。