2012-09-06 20 views
4

我似乎不明白爲什麼下面的代碼只打印兩次「TEST」。php在靜態函數裏面沒有超載

<?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網站說(link):

屬性重載只能在對象範圍內。這些神奇的方法不會在靜態上下文中觸發。因此這些方法不應該被聲明爲靜態的。從PHP 5.3.0開始,如果其中一個魔術重載方法聲明爲靜態,則會發出警告。

但我認爲他們試圖說你應該聲明靜態的魔術方法。例如: -

公共靜態函數__get(){}

加上其實我在事實上對象環境中使用它。 $ a = new self();從變量$ a中的類A返回一個實例。然後我使用$ A->測試(對象上下文海事組織?)來獲取私人「測試」變量這反過來應該超載...

我很困惑...

回答

2

看來,在A:: someStaticMethod的情況下,PHP允許您直接訪問私有變量$test,所以魔法方法不會執行。如果你從那裏開始echo $a->test;,你會看到它被訪問。

這是預期的行爲,根據PHP Manual

同一類型的對象將有機會獲得對方的私有和保護成員,即使他們是不一樣的情況。這是因爲實現特定的細節在這些對象內部時是已知的。

3

manual

當與尚未聲明或在當前作用域中不可見的屬性或方法進行交互時,將調用重載方法。

當您調用靜態方法someStaticMethod()時,私有$ test在當前範圍內可見,所以不調用magic __get方法。

+0

如果我可以的話,我會投你兩個接受的一個。 :(。但是我將如何能夠從靜態方法訪問$ test someStaticMethod()?我得到它是「在當前範圍內可見」。但我不能從靜態上下文訪問實例上下文嗎?所以幾乎我不會能夠直接從someStaticMethod()直接訪問$ test嗎?Anywayz ...這在* ss中有點痛苦,因爲我使用重載進行延遲加載,所以這對我來說非常煩人...任何解決方法它呢? – Marc

+0

@Marc你不能,但我提出了這個答案給它應有的功勞。我們用不同的方式得出了同樣的結論。 – bfavaretto