1.PHP中可以靜態調用非靜態方法麼?
今天我被問到PHP中可不可以使用 className::methodName() 的方法來調用一個沒有聲明Static的方法。在我的印象中,我好像是見過這種用法,但又有些不確定。大家都知道,在手冊或者教程裡,方法被分為靜態方法和非靜態方法,通常我們靜態調用的方法,肯定是靜態方法。
那如果我們調用了非靜態方法會怎麼樣呢?首先做測試.<?php
class test{
function test(){
echo 'it works';
}
}
test::test();
執行以下,返回錯誤如下Fatal error:
Non-static method test::test() cannot be called statically in
/home/×××/test.php
on line 7 Call Stack: 0.0002 332548 1. {main}()
/home/×××/test.php:0
這個時候,可能大家就會認為靜態調用非靜態方法是行不通的了,但其實,結論下的過早了,因為test()這個方法比較特殊,與類同名,是構造方法。
我們繼續測試。<?php
class test{
function test(){
echo 'it works';
}
function test2(){
echo 'it works too';
}
}
test::test2();
執行結果:
it works too
這說明,靜態調用非靜態方法是可行的,但是靜態調用構造方法是不可以的。為了驗證這個結論,我又做了如下測試:
<?php
class test{
static function test(){
echo 'it works';
}
}
test::test();
執行的結果如下:
Fatal error: Constructor test::test() cannot be static in
/home/xxx/test.php on line 9
構造方法不能聲明靜態,所以上面的推論正確。
但這個結果的確是很特殊的,因為可能只有PHP可以靜態調用非靜態方法,我用Java做了實驗,如果靜態調用非靜態方法會報如下錯誤:
Cannot make a static reference to the non-static method
showString() from the type HelloWorldApp
其他語言我沒有一一嘗試,但這已經足夠來說明PHP的特殊之處,關於為什麼PHP會有這樣的情況我暫時沒有找到相關說明。
2.靜態調用非靜態方法是否應該被應用?
那我們是不是可以使用這種方法來代替static方法呢? 首先在代碼的可讀性上來看,靜態調用非靜態方法當然是不被推薦的,這會讓維護者產生疑惑。
接下來我們再做一些實驗,來看一下靜態調用非靜態方法在效率上是否會有一定的優勢。<?php
class test{function test2(){}}
for($k=0; $k<10000; $k++)
{
test::test2();
}
上面代碼在我這裡的執行時間是18到28毫秒,我們再來測試標准的寫法。<?php
class test{static function test2(){}}
for($k=0; $k<10000; $k++)
{
test::test2();
}
上面的代碼執行時間在5到10毫秒之間,這樣看來,靜態調用非靜態方法的效率要比標准的靜態方法調用低的多,所以在效率上也不推薦靜態調用非靜態方法。