4

我似乎不明白为什么下面的代码只打印两次“TEST”。

<?php

class A {
    private $test = "TEST<br />";

    public static function getInstance() {
        return new self();
    }

    public static function someStaticMethod() {
        $a = new self();
        $a->test;
    }

    public function __get($args) {
        echo $this->$args;
    }
}

/* echo's "TEST" */
$a = new A();
$a->test;

/* echo's "TEST" */
$a2 = A::getInstance();
$a2->test;

/*
No output... eeerhm... how come?
Why is $a->test (inside someStaticMethod()) not being overloaded by __get ??
*/
A::someStaticMethod();

?>

PHP网站说(链接):

属性重载仅适用于对象上下文。这些魔术方法不会在静态上下文中触发。因此这些方法不应该被声明为静态的。从 PHP 5.3.0 开始,如果其中一个魔术重载方法被声明为静态,则会发出警告。

但我认为他们试图说你应该将魔法方法声明为静态的。例如:

公共静态函数 __get(){}

再加上我实际上在对象上下文中使用它的事实。$a = 新的自我();从变量 $a 中返回类 A 的实例。然后我使用 $a->test (object context imo?) 来获取私有的“test”变量,而这个变量又应该被重载......

我很困惑...

4

2 回答 2

3

手册

当与尚未声明或在当前范围内不可见的属性或方法交互时,将调用重载方法。

当您调用静态方法someStaticMethod()时,私有 $test 在当前范围内可见,因此不会调用魔术 __get 方法。

于 2012-09-06T19:21:46.767 回答
2

似乎,在 的上下文中A:: someStaticMethod,PHP 允许您直接访问私有变量$test,因此魔术方法没有执行。如果你echo $a->test;从那里,你会看到它正在被访问。

根据PHP 手册,这是预期的行为:

相同类型的对象将可以访问彼此的私有成员和受保护成员,即使它们不是相同的实例。这是因为在这些对象内部时,特定于实现的细节是已知的。

于 2012-09-06T19:25:58.477 回答