3

我最近阅读了有关在 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();执行?实例调用应该在 bar() 方法的上下文中进行,不是吗?它是PHP的功能吗?__callStatic()A

加法1:

此外,如果我不使用魔法方法并明确调用,一切都会按预期工作:

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

结果:

I'm the foo() method of A class
Current class of $this is B
Called class is B
4

2 回答 2

3

bar()方法中C,您有A::foo();

public function bar() {
    A::foo();
}

由于此方法既没有创建 的实例A,也没有C扩展A,因此::运算符被视为尝试调用静态方法的静态运算符A::foo()。因为foo()未在 上定义A,所以它回退到该__callStatic()方法。

如果您希望它在不扩展的情况下调用非静态方法A,则必须创建一个实例A

class C {
    public function bar() {
        $aInstance = new A();
        $aInstance->foo();
    }
}
于 2013-08-28T12:30:41.003 回答
0

这是因为在这种情况下我们没有A类的实例。请注意

 class B extends A

因此new B,我们可以访问非静态版本的A->foo.

C不扩展A,因此只有静态方法A可用。

于 2013-08-28T12:34:54.527 回答