为什么调用__call而不是__callStatic

时间:2016-12-16 07:44:41

标签: php

我尝试在SO上引用此question,但仍然没有得到它。

<?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();
    }

    public function foo() {
        parent::foo();
    }
}

(new B)->bar();
(new B)->foo();

根据我的理解,bar函数静态调用类foo上的A方法,但foo方法使用{{1}的实例调用方法这是A的父级。我期待它应该给我:

B

但是,显然,我得到了:

I'm the __callStatic() magic method
I'm the __call() magic method

2 个答案:

答案 0 :(得分:3)

A::foo(),取决于上下文,并不总是静态调用。由于B::bar()内部$this对象存在,foo中声明了名为A的静态方法 BA的子类,然后将进行实例调用,因此将调用__call魔术方法。如果不满足任何这些条件,则会进行静态调用。

答案 1 :(得分:3)

来自相关的issue

  

... A::foo() 不一定是静态调用。也就是说,如果foo()不是静态的并且存在兼容的上下文($this存在且其类是目标方法的类或其子类),则将进行实例调用。 / p>

如果foo()static,则按预期运行:

class A {
    public function __call($method, $parameters) {
        echo "I'm the __call() magic method $method".PHP_EOL;
    }

    public static function __callStatic($method, $parameters) {
        echo "I'm the __callStatic() magic method $method".PHP_EOL;
    }
}

class B extends A {
    public static function foo() { // <-- static method
        parent::foo();
    }
}

(new B)->foo();
  

我是__callStatic()魔术方法foo