2017-01-19 46 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,我们来知道和爱。

有什么理由比其他方法更喜欢一种方法吗?

两者都可以工作。在处理类时,您只需获得更多的功能和灵活性。