2016-04-03 33 views
6

我對found PHP解釋器有些奇怪的(對我來說)行爲,我不確定在生產中是否安全使用它。通過範圍解析運算符調用非靜態方法

當我們調用Foo::bar()Foo類沒有靜態bar方法,但它具有非靜態bar方法,解釋器將調用非靜態barnull(是的,這聽起來很可笑)。我期望在這種情況下調用__callStatic。但這不是出於某種原因正在發生的事情。

我隨後發現這種行爲的一個方便的使用:提供類具有相同的名稱這樣的靜態和非靜態方法:

class Foo 
{ 
    public function bar(){ 
     if (isset($this)) { 
      $this->nonStaticBar(); 
     } else { 
      static::staticBar(); 
     } 
    } 

    private function nonStaticBar() { 
     echo "Non-static\n"; 
    } 

    private static function staticBar() { 
     echo "Static\n"; 
    } 
} 

(new Foo())->bar(); // Output: "Non-static" 
Foo::bar(); // Output: "Static" 

是的,我知道,這種做法是不優雅和架構錯誤。問題是如果使用這個「功能」是否安全(符合標準)。當isset($this)可以等於false時是否還有其他情況?

回答

3

雖然您的上述示例確實有效,但這不是最佳做法。 這是PHP文檔here所承認,並指出在PHP 7版本之前的版本中,如果E_STRICT錯誤報告已啓用,它會發出錯誤:

Strict Standards: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22 

此外,在PHP版本7及以上的靜態調用靜態函數已被棄用,並將在執行後導致以下錯誤:

Deprecated: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22 
+0

感謝您對文檔的引用。我相信在這種情況下必須調用__callStatic。該類不具有這種名稱的靜態方法。並且文檔指出''__callStatic()在靜態上下文中調用不可訪問的方法時被觸發。「# – Kolyunya

+0

@Kolyunya當我嘗試在靜態(或非靜態)內分配/重新分配變量'$ this'時,我注意到了一個有趣的事情)方法是它會返回致命錯誤'致命錯誤:無法在/ Path/to/file.php中重新分配$ this。所以,儘管這不是最佳實踐,但我無法想象出另一個'isset($ this)'等於'false'的情況。 –

相關問題