2017-04-26 85 views
5

據我所知,靜態方法必須它們的類類型的實例對象,並因此的狀態沒有訪問在error.But對象引用$this內他們的結果可以參考使用對象的靜態方法構件操作者->PHP靜態方法

$obj->staticMethod(); 

甚至可以通過參數傳遞它的狀態。

$para1 = $obj->para1; 

$para2 = $obj->para2; 

$obj->staticMethod($para1, $para2); 

當靜態環境中靜態解析時,最後一個示例如何可能?如果有人能向我解釋靜態代碼在php代碼中的一般行爲。你甚至可以談談C相關的概念,如果它會幫助。

+0

密切相關:[如果我以非靜態方式調用靜態方法?](// stackoverflow.com/q/12874376/962603) –

+2

將靜態方法看作是使用時髦句法。類靜態成員也是如此。唯一使它們與全局對象(函數,變量)不同的是可見性說明符(protected,private)。 – axiac

回答

1

由於您聲明您已經瞭解static的含義,因此我會跳過該說明。

但是,引用PHP的documentation on the static keyword可能仍然很好。特別是以下兩個警報很重要(真的很難看清楚)。

注意      在PHP 5,調用非靜態方法靜態生成E_STRICT級警告。

而這一個(斜體強調我的)。

警告      在PHP 7,調用非靜態方法靜態已過時,會產生E_DEPRECATED警告。 支持靜態調用非靜態方法將來可能會被刪除。

因此,削減長話短說:是的,你的榜樣將運行(現在),因爲PHP解釋器將嘗試修復你的錯誤你。你應該永遠不要這樣做。 PHP解釋器將做什麼是:

說你的$objFoo類型。然後,它會讀取

$obj->staticMethod($para1, $para2); 

斷定staticMethodstatic,而是執行

Foo::staticMethod($para1, $para2); 

這當然是完全正常的通過,是Foo實例的性能參數。 staticMethod參數來自哪裏並不重要。


更詳細地說明了一下,爲什麼這個作品,而在static方法使用$this是不允許的。

您可以將常規方法看作static函數,它們有一個額外的功能:它們收到一個隱式參數$this$this的值僅僅是調用該方法的對象。因此,$obj->do($a, $b, $c)相當於撥打Foo::do($obj, $a, $b, $c)並命名爲do,$this的第一個參數。這很方便,因爲我們現在可以輕鬆定義在對象實例上工作的方法,而無需一遍又一遍地重複說明此實例是我們方法的參數。大。

現在回到static的功能。與普通方法唯一的區別是它們不會收到這個隱含的$this參數。因此,在他們裏面使用$this是無效的。不是因爲它被禁止,而是因爲它沒有引用任何東西。 PHP沒有(也不能)知道$this應該指向什麼。

另一種方法來看看它。說我們的Foo類有兩個屬性:$para1$para2,兩個數字。假設你寫了一個方法返回這些數字的總和。一種方法是做到這一點:

public static function sum($para1, $para2) { 
    return $para1 + $para2; 
} 

很好。作品。然而,它是這樣稱呼它是討厭的

$sum = Foo::sum($obj->para1, $obj->para2); 

所以,這是什麼方法是!

public function sum(/* implicit $this parameter */) { 
    // write looking up the properties once inside the function, instead 
    // of having to write it every time we call the function! 
    return $this->para1 + $this->para2; 
} 

// ... 

$sum = $obj->sum(); // $obj is passed implicitly as $this 

因爲靜態函數不接受隱$this參數,使用$this它們的內部就像是試圖使用$undefined當你從來沒有定義它。因此,無效。

+0

可以肯定地說,靜態數據比手動可以存檔的文件要多得多。 –

+0

@CholthiPaulTtiopic我相信手冊是相當完整的,但事實上,他們本可以強調這一點。這是否回答你的問題?我很樂意詳細說明。 –

+0

我還是不明白爲什麼PHP在靜態方法內禁止'$ this',同時允許我們仍然像上面的例子那樣做東西。 –

0

靜態裝置用簡單的術語類成員,A 靜態數據成員是不論被創建或不對象的類內訪問靜態功能也是致力於整個班級的功能。靜態函數只能處理靜態數據,有時可能會有所不同。儘管靜態是專用的,但您可以使用對象訪問它們。它允許所有語言。爲什麼?由於可行性。如果一個對象無法訪問靜態成員,那就是一個限制。