WordPress 中的 PHP 命名空间——一本严肃的指南
已发表: 2018-10-16PHP 命名空间已经有将近十年的历史了。 是的,十年过去了(是的,你变老了)。 尽管 PHP v5.3 发布已经过去了十年,但许多开发人员仍然对命名空间没有基本的了解。 说实话WordPress 不使用命名空间,所以“如果你只使用 WordPress,你不需要知道如何使用命名空间。” 您不需要成为命名空间忍者,但掌握基础知识很简单,而且对您有好处。
PHP 命名空间已经存在了十年,您仍然不使用它们,因为#wordpress 也没有? 阅读并在 2 分钟内开始使用它们! #发展
点击推文当没有命名空间支持时——使用前缀
很长很长一段时间以来,PHP 都没有原生命名空间支持。 这就是 WordPress 和许多其他大型代码库不使用本机命名空间的原因。 它们在需要时不在身边,因此使用了前缀。
命名空间很重要,因为它确保您的函数write_to_log()
尚未由另一段代码定义。 为了避免名称冲突,全局范围内的所有内容都需要一个前缀,因此该函数变为awesome_project_write_to_log()
并且所有其他函数和变量也获得了awesome_project_
前缀。 简单的? 这是! 漂亮的? 不完全是。
该方法有一些替代方法,例如静态方法封装。 您将所有函数包装在一个类中并将它们声明为静态方法。 然后调用My_Class::my_function()
而不是调用my_function()
() 。 更好的? 有点,但仍然不是正确的命名空间。
让我们看看命名空间如何允许多个代码段(或如果需要,可以使用包)使用相同的类和函数名而不会发生冲突。 或者正如 PHP 手册所说——它们如何启用代码封装。 它们与文件和文件夹的类比也很明显——在很多方面命名空间的行为就像文件夹一样,所以我将从手册中复制/粘贴;
在任何操作系统中,目录用于对相关文件进行分组并充当其中文件的命名空间。 例如,文件 foo.txt 可以同时存在于目录 /home/greg 和 /home/other 中,但 foo.txt 的两个副本不能共存于同一目录中。 要访问 /home/greg 目录之外的 foo.txt 文件,我们必须使用目录分隔符将完整目录名添加到文件名前,以获取 /home/greg/foo.txt。
声明命名空间——记住第一行
关键字namespace
必须是文件中的第一行代码(不包括注释和任何非 PHP 内容)。 命名空间只影响类、接口、函数和常量。 它们不影响变量。 您可以在多个文件中定义相同的命名空间,从而允许您将代码拆分为多个文件。 子命名空间允许在命名空间中定义层次结构,就像在文件夹中一样,使用反斜杠namespace myproject\level1\level2
。 这些是声明命名空间的基本规则和几乎所有规则。
// file-A.php contains a function under the myCompany\PackageA namespace namespace myCompany\PackageA; function do_something() { // do things }
// file-B.php contains a function with the same name // but under a different namespace namespace myCompany\PackageB; function do_something() { // do things }
尽管可能,但我强烈建议不要将多个命名空间组合到一个文件中。 相信我,你迟早会忘记你做过,然后调试一个 2 分钟的错误需要两个小时。 但是,如果必须,这里是语法。
// do not put multiple namespace declarations into the same file // but if you must, here's the syntax namespace MyFirstProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } namespace MySecondProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } // any code after this has to go in the global namespace namespace { $some_var = 1; function_in_global_namespace(); }
使用命名空间——记住文件夹
正如我已经说过的——命名空间与文件夹非常相似。 假设文件foo.txt
在您当前的文件夹中; 你可以用一个简单的foo.txt
来引用它。 如果您比具有foo.txt
文件的文件夹高一级,则需要使用相对路径../foo.txt
或绝对路径/folder1/folder2/foo.txt
。 没有什么花哨。 命名空间使用相同的范例。
// remember after declaring a namespace // all our code is in it; like when you're working in a folder namespace mycompany\project; function foo() {} class foo { static function staticmethod() {} } // resolves to mycompany\project\foo() because of line #3 foo(); // likewise, resolves to mycompany\project\foo::staticmethod() foo::staticmethod(); // constant are affected by namespaces too // so we're working with mycompany\project\FOO echo FOO; // this is a relative path // resolves to mycompany\project\subnamespace\foo() subnamespace\foo(); // static methods are no different // mycompany\project\subnamespace\foo::staticmethod() subnamespace\foo::staticmethod(); // a full namespace path starts with a backslash // it resolves exactly to what it says it does \otherNamespace\Bar\foo(); // again same thing for a constant, full path nothing magical echo \otherNamespace\Bar\FOO;
看看 PHP 手册中的use
关键字——例子很棒。 它提供了一种将代码从其他 PHP 命名空间导入当前命名空间或使用别名引用外部(完全限定)名称的方法。
是的,您需要命名空间并且应该使用它们
通过查看 WordPress 的源代码,这一点非常明显——您不必使用命名空间,但您必须使用一些命名空间的方法。 在 WP 的情况下以wp_
为前缀。 那么,如果我们已经在做,为什么不正确地做呢?
PHP 中的命名空间很容易集成到任何开发工作流程中。 它们简化了自动加载、文件命名,并且通常使代码更清晰。 重构旧代码从来都不是一个流行的任务(不管编码语言如何),所以我不会告诉你继续重构一个工作的 2 MB 项目,以便你可以说你使用命名空间。 但是,我会坚持在处理新项目时使用命名空间。 你很快就会感谢自己的。
关于命名空间的官方 PHP 文档非常棒! 代码示例很干净,评论对现实世界很有帮助。 一定要浏览它,即使您认为不需要。