2011-02-03 94 views
5

這兩段代碼有什麼區別?php靜態方法問題

class something { 

    static function doit() { 
     echo 'hello world'; 
    } 
} 

something::doit(); 

和相同的,但沒有static關鍵字

class something { 

    function doit() { 
     echo 'hello world'; 
    } 
} 

something::doit(); 

他們都工作,同樣是它更好地使用靜態關鍵字?我的理解是,如果使用靜態方法,它不會實例化類?

回答

11

第二個例子是技術上不正確 - 如果你打開E_STRICT錯誤報告,你會看到,PHP實際上是拋出一個錯誤。

PHP Strict Standards: Non-static method something::doit() should not be called statically in...

換句話說,它很好,讓你無論如何調用函數。

0

二位不應該工作,你應該把它通過

$something = new something(); 
$something->doit(); 

靜態功能,用戶可以調用類中的一個函數沒有consturcting它。 所以基本上如果你有一個類來處理用戶,那麼一個記錄用戶的函數應該是一個靜態函數,就像在那個類的構造函數中一樣,你可能會收集用戶信息,而且你不能在沒有登錄的情況下這樣做。

+0

它適用於PHP4及以下版本。 – Arvin 2011-02-03 10:00:39

0

你的第二個例子是錯誤的。使用靜態方法不會創建類的實例。你的第二個例子應該是這樣的:

$x = new something(); 
$x->doit(); 
1

區別在於可以使用靜態函數而無需創建類的實例。

看看這個很棒的PHP OOP初學者教程here。它在靜態屬性和方法部分的一個示例中更詳細地解釋了該部分。

0

靜態方法應該被聲明爲static的至少有兩個方面的原因:
a)使用E_STRICT的error_reporting時,調用非靜態方法,靜態會產生錯誤:基於關鍵詞static一些IDE的過濾方法可能
Strict standards: Non-static method something::doit() should not be called statically
B)在自動完成時運行。

4

除了其他有效的答案,第二個例子工作的原因也是由於PHP處理對象和調用(除了PHP 4兼容性)的一個怪癖。調用另一個實例中靜態聲明的非方法將允許您訪問其他類上的類方法,就好像它們是本地方法一樣。要理解,我們舉個例子:

class A { 
    public function foo() { 
     echo get_class($this) . "\n"; 
    } 
} 

class B { 
    public function bar() { 
     A::foo(); 
    } 
} 

$a = new a(); 
$a->foo(); // "A" 
$b = new B(); 
$b->bar(); // "B" 

你看到那裏發生了什麼?由於您從另一個類的實例中調用A::foo()方法,因此PHP將該調用視爲處於同一實例中。請注意,除了B調用A這一事實之外,AB之間沒有關係。在A->foo()之內,如果我們做了$this instanceof A(或$this instanceof self),它會失敗並返回false!很不尋常...

現在,我第一次以爲這是一個bug,但after reporting it,它顯然是設計。這是even in the docs

請注意,這不會與E_STRICT模式啓用。如果您聲明方法爲static,它也不起作用。