在我公司的代碼庫中,我看到了在靜態和對象上下文中使用的函數。對於例如A類具有一個函數b(),該函數同時使用A :: b()和/或object_of_type_A-> b()來調用。我知道如果嚴格打開,這會引發錯誤。但我想知道這是否是一種不好的做法,如果是的話,那爲什麼?感謝任何答案。應該在靜態和對象上下文中使用函數
讓我知道如果我沒有任何意義。我會很樂意澄清。
在我公司的代碼庫中,我看到了在靜態和對象上下文中使用的函數。對於例如A類具有一個函數b(),該函數同時使用A :: b()和/或object_of_type_A-> b()來調用。我知道如果嚴格打開,這會引發錯誤。但我想知道這是否是一種不好的做法,如果是的話,那爲什麼?感謝任何答案。應該在靜態和對象上下文中使用函數
讓我知道如果我沒有任何意義。我會很樂意澄清。
下面是一些測試代碼:
<?php
error_reporting(E_ALL | E_STRICT);
class Foo{
public function a(){
}
public static function b(){
}
}
$MyFoo = new Foo;
Foo::a(); // Strict Standards: Non-static method Foo::a() should not be called statically
Foo::b();
$MyFoo->a();
$MyFoo->b(); // No complaints
?>
PHP/5.3警告非靜態方法是靜態調用,因爲他們是受故障這是很好的,只要你想訪問$this
。但它並不會抱怨靜態函數的對象上下文調用:沒有什麼可以出錯的。 This behaviour is documented:
聲明類屬性或方法 靜態使他們訪問 不需要的 類的一個實例。聲明爲靜態 屬性可以不與 實例化的類對象(雖然 靜態方法可以) [...] 因爲靜態方法調用 而不創建對象 的一個實例中,僞變量進行訪問$這是 在聲明爲靜態的方法 內不可用。
所以,就PHP而言,你在代碼庫中發現的東西並沒有錯。不過,我認爲這有點混亂。
+1中無效,我想這正是我正在尋找的...所以,行爲是正確的,但令人困惑: - )...是否有任何其他原因需要關注?感謝您的答案.. – pinaki 2010-07-10 19:06:46
我不是一個PHP的傢伙,但這聽起來就像Java,它允許但不鼓勵。
如果它是靜態的,我會強烈建議只能以靜態方式調用它。否則它看起來喜歡它取決於你應該打電話給它的對象的狀態。
在Java中,最好的例子是Thread.sleep()
。這是一種靜態方法,可以使當前線程始終處於睡眠狀態。不過看這代碼:
Thread t = new Thread(someTask);
t.start();
t.sleep(1000);
是什麼看起來像的代碼是幹什麼的?它似乎將其他線程休眠,而實際上它將成爲當前正在休眠的線程。當你將其更改爲普通的靜態調用,這是比較明顯的:
Thread.sleep(1000);
這並不是指t
,所以必須是對當前線程。
除非有特定於php的地方,通過變量調用靜態方法會給你一些多態性,我建議你堅持以靜態方式調用它。嚴格模式告訴你這樣做的事實是一個非常強大的暗示,IMO :)
還有沒有涉及多態性。該函數在靜態以及對象上下文中都被調用。我仍然不清楚,但如果這只是最佳實踐或任何其他問題涉及此處。謝謝你的答案。 – pinaki 2010-07-09 06:12:14
使用它目前沒有任何傷害,除非當被稱爲靜態函數時,您無法訪問$這個成員。
嚴格錯誤的原因是因爲沒有將您的代碼寫入嚴格的標準可能會導致錯誤發生,因爲缺乏勤奮。在將來它可能會導致你的代碼被破壞。一個靜態函數沒有$這個成員,它可能會破壞參數傳遞。
發揮它的安全只使用A :: b()類型調用調用靜態函數。
DC
感謝您的回答。目前,它並沒有在嚴格函數中使用$ this。 – pinaki 2010-07-09 06:15:25
靜態成員函數不能期望$ this是有效的,因此不應該使用$ this指針。通過比較,C++具有靜態成員和非靜態成員,儘管它通常使用隱式指針,您可以使用this-> staticfunction()調用靜態成員函數,而不會出現任何問題。但如果你試圖在靜態成員函數中使用'this',它會導致編譯時錯誤,因爲這在靜態函數 – DeveloperChris 2010-07-12 01:20:59
關於在一個靜態函數中訪問$ this,我發現了一些有點古怪的事情(可能會在PHP的更高版本中進行更改,儘管我認爲我運行了5.2版本)。
你可以在這裏看到它,但它在瑞典語。但使用谷歌翻譯,它應該是可以理解的。
+1,非常有趣的帖子(但與我的問題無關;-)).. – pinaki 2010-07-10 19:04:51
即使他調用foo :: getname(),它仍然沒有問題,它仍然被稱爲非靜態成員,因此$這指向第一次調用中的'foo'類和第二次中的'bar'類,因此他得到並調用奇怪的結果正是他應該得到的結果。 – DeveloperChris 2010-07-12 01:02:22
如果您的代碼引發錯誤,請修復它們。如果您可以通過關閉E_STRICT來解決問題,則無關緊要。它在那裏,你知道如何解決它,所以修復它。 – Gordon 2010-07-09 06:29:09
@gordon - 這裏的問題是函數沒有被定義爲靜態的,也沒有使用任何類變量($ this)。所以,雖然我可以繼續並將所有地方改爲靜態/對象,但我需要明確的理由在組織中指定我的工作......我希望現在這個問題更有意義。 – pinaki 2010-07-10 18:59:24
它已經有意義了:)但我認爲你不應該向你的公司解釋你爲什麼修復觸發錯誤的代碼,即使它只是* E_STRICT。你看,PHP已經告訴你不應該這樣調用,所以爲什麼不去注意這一點。在旁註中,如果您有興趣提高組織中的代碼質量,請查看http://qualityassuranceinphpprojects.com/pages/tools.html – Gordon 2010-07-10 19:34:01