2017-01-19 47 views
2

什麼是在一個命名空間創建一個全局函數(從全局命名空間調用它)之間的區別:PHP:類中的靜態方法和命名空間中的全局函數?

<?php 
namespace MyNamespace { 
    function MyFunction($x, $y) { 
     return $x + $y; 
    } 
} 

namespace { //global code... in a new file 
    var_dump(MyNamespace\MyFunction(1,2)); 
} 

,並創建一個靜態類的方法,並從全局命名空間?:

<?php 
class MyClass { 
    public static function MyFunction($x, $y) { 
     return $x + $y; 
    } 
} 

var_dump(MyClass::MyFunction(1,2)); 
調用

是否有任何理由更喜歡一種方法而不是另一種?

回答

2

有什麼理由比其他方法更喜歡一種方法嗎?

(以下假定你問/指的是靜態類方法,並在命名空間的功能是不同的)

歷史(命名空間到達之前),人們被迫使用靜態函數的類不污染全局名稱空間。這是您可能更經常遇到此方法的原因之一。

如果您需要訪問類的數據,或者如果您想留下一扇門來重寫後代類(所謂的「靈活性和功能」),您可能更喜歡使用靜態方法。

當所有你想要的是......呃,啊......一個函數時,你可能更喜歡命名空間函數。想想一些util,函數或集合函數,比如compose/partial,retry,filter/map/some/every等等。你可能不會期望這個被子類覆蓋,對吧?它不需要訪問一些靜態類成員。

儘管(名稱空間)函數有一個特別令人討厭的問題,那就是類不受影響。它是自動加載的。簡而言之,目前有no way to autoload a function。這也是你在實踐中更經常遇到類的靜態方法(當它們不一定需要時)的另一個原因。

+0

不能自動加載的好處。我沒有考慮過。 – mcmurphy

3

主要區別是全局命名空間只能有一個函數名爲MyFunction

使用命名空間,每個命名空間可以擁有自己的MyFunction副本。這使您可以靈活地創建一個通用的API,而不必提出聰明的名字。

例如:

namespace Mail { 
    public static function send() { 
     // Send Mail 
    } 
} 

namespace SMS { 
    public static function send() { 
     // Send Text Message 
    } 
} 

這是不可能用單一的全局命名空間。但是現在您有一個可預測的界面來呼叫Mail\send()SMS\send()

對於類,創建這些契約的能力比命名空間中的函數效果好得多,因爲您可以構建接口並使用抽象。

例如:

abstract class Mail { 
    public static function send() { 
     // Create empty implementation (have to do this because it is static) 
    }; 
} 

class MailChimp extends Mail { 
    public static function send() { 
     // Send Mail 
    } 
} 

class MailGun extends Mail { 
    public static function send() { 
     // Send Mail 
    } 
} 

這樣,我們現在可以在「郵」命名空間的東西,而且還有效地根據郵件的具體實現,並保持共同send() API,我們來知道和愛。

有什麼理由比其他方法更喜歡一種方法嗎?

兩者都可以工作。在處理類時,您只需獲得更多的功能和靈活性。