PHP:Namespace中的Class vs Global函数中的静态方法?

时间:2017-01-19 18:26:36

标签: php static namespaces global

在命名空间中创建全局函数(并从全局命名空间调用它)之间有什么区别:

<?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 个答案:

答案 0 :(得分:5)

  

有没有理由更喜欢一种方法而不是另一种?

(下面假设您要求/引用静态类方法与命名空间中的函数之间的区别)

历史上(在命名空间到达之前),人们被迫使用具有静态函数的类来不污染全局命名空间。这是您可能更频繁地遇到此方法的原因之一。

如果您需要访问类的数据,或者如果您想要在后代类中覆盖它们,那么您可能更喜欢使用静态方法(所谓的“灵活性和功能性”#39)一些人。

当你想要的只是......呃,嗯......一个函数时,你可能更喜欢命名空间函数。想想一些util,functional或集合函数,比如compose / partial,retry,filter / map / some / every等。你可能不希望在子类中覆盖它,对吧?它既不需要访问某些静态类成员。

但是(命名空间)函数存在一个特别恼人的问题,即类不会受到影响。它是自动加载的。简而言之,目前有no way to autoload a function。这也是你可能在实践中经常使用静态方法(当他们不一定需要时)遇到课程的另一个原因。

答案 1 :(得分: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
    }
}

有了这个,我们现在可以在&#34; Mail&#34;下进行命名空间,但也可以在邮件的特定实现下有效地命名,并且保持通用send() API我们&# 39;我来了解和爱。

  

有没有理由更喜欢一种方法而不是另一种?

要么工作。在处理类时,您只需获得更多功能和灵活性。