超越前缀:PHP 命名空间的 WordPress 开发人员指南

已发表: 2019-11-12

前缀一切。

这是一句与 WordPress 软件本身一样古老的格言。 长期以来,前缀一直是 WordPress 开发人员的标准,以至于很难想象有什么不同。 但是,是时候来点新东西了。 好吧,它早就过期了,但是 WordPress 在更大的 PHP 世界中的标准实践有点落后。

前缀是创建项目名称的代码友好版本并将其粘贴到全局命名空间中的函数、类和其他事物的前面的做法。 例如,您将命名一个函数tavern_get_post()而不是get_post()以避免函数名称冲突,这会导致致命错误。

前缀是“命名空间”的一种形式,它只是表示该空间中的名称属于特定项目的一种奇特方式。 然而,在 PHP 语言没有解决方案的时候,前缀(和不太常见的后缀)是一种黑客行为。

PHP 5.3 引入了命名空间的官方方法,因此该标准已经存在多年。 因为 WordPress 5.2 将 PHP 的最低要求提高到了 5.6,所以现在是开发人员摆脱旧习惯并赶上 PHP 世界其他地方的时候了。

命名空间(几乎)一切

PHP 命名空间仅涵盖以下项目。

  • 课程
  • 接口
  • 性状
  • 职能
  • 使用const关键字声明但未使用define()的常量

当涉及到全局命名空间中的脚本句柄、图像大小名称、数据库选项和其他项目时,您仍然必须为它们添加前缀。 这些是 ID,超出了 PHP 命名空间的范围。

如何创建命名空间

命名空间很容易声明。 在要使用特定命名空间的任何 PHP 文件的顶部,如以下代码片段所示声明它。

 <?php

命名空间酒馆;

这行代码的作用是声明这个特定文件中的所有内容都具有Tavern的命名空间。

看一下该命名空间下的一个简单函数,用于输出Hello, World! 信息。

 <?php

命名空间酒馆;

功能你好(){
    _e('Hello, World!', 'example-textdomain' );
}

如果遵循旧的前缀规则, hello()将被命名为tavern_hello() 。 但是,命名空间并非如此。 hello()函数封装在Tavern命名空间中,不会与其他名为hello()的函数发生冲突。

类和接口与函数的工作方式相同。 类名称为Article时,类文件可能如下所示。

 <?php

命名空间酒馆;

类文章{
    // ...
}

注意:每个文件应该只有一个类或接口。 如果您打算使用自动装载机,这一点尤其重要。

如何命名命名空间

开发人员喜欢争论如何命名事物,并且没有一刀切的解决方案。 最重要的规则是唯一的,以避免与其他项目的代码发生冲突。 最好的方法之一是将顶级Vendor命名空间与Package子命名空间一起使用。

假设供应商命名空间是Tavern并且有问题的项目是一个名为News的 WordPress 主题。 项目的命名空间可能如下所示。

 <?php

命名空间酒馆\新闻;

对于某些开发人员来说,这可能有点冗长。 如果您的项目名称已经相当独特,例如“Awesomesauce”,您可能只想使用以下名称。

 <?php

命名空间 Awesomesauce;

您至少会想为自己制定某种标准约定。 最终,您会想要了解自动加载等内容,因此在您的所有项目中都遵循一个系统会有所帮助。 随意阅读 PHP-FIG Autoloader 标准。

将类和函数导入不同的命名空间

当您需要使用与当前命名空间不同的命名空间中的类或函数时,您需要导入它。 这是通过 PHP 中的use关键字完成的。

use语句必须在namespace声明之后。 它还应该引用完全限定的类名。 以下代码将Tavern\Helpers\Post类导入到具有不同命名空间的文件中。

 <?php

命名空间酒馆\模板;

使用酒馆\助手\邮政;

导入后,您可以安全地直接使用Post类,如下一个片段所示。

 $post = 新的帖子();

从 PHP 5.6 开始,您还可以分别使用use functionuse const关键字从其他命名空间导入函数和常量。 以下代码块演示了如何同时导入函数和常量。

 <?php

命名空间酒馆\模板;

使用函数 Tavern\Helpers\func_name;
使用 const Tavern\Helpers\CONSTANT_NAME;

别名类和函数

最终,您将遇到需要导入与当前命名空间中的类或函数同名的类或函数的情况。 您可能会认为这是命名空间旨在解决的问题。 幸运的是,PHP 提供了一种在导入时创建别名的方法。

假设您有一个名为Tavern\User的类,并且需要实现Tavern\Contracts\User接口。 导入接口时,您需要创建一个别名,如下所示。

 <?php

命名空间酒馆;

使用 Tavern\Contracts\User 作为 UserContract;

类用户实现 UserContract {
    // ...
}

附加到use语句末尾的as UserContractUser界面创建了一个别名。 您可以安全地使用新的UserContract名称而不会出错。

类、接口、函数和常量都遵循相同的方法来创建别名。

基于命名空间组织文件夹结构

在更广泛的 PHP 世界中,命名空间与项目的文件和文件夹结构相匹配是标准做法。 这样做可以让其他开发人员轻松地在您的项目中轻松定位代码。 它还使得构建自动加载器以按需加载类变得简单。

通常,所有 PHP 代码都应该放在项目中的/src/inc或类似名称的文件夹中。 示例插件文件和文件夹结构可能如下所示。

 /插件名称
    /src
        /核
            /激活.php
            /Setup.php
        /看法
            /post.php
            /Page.php

如果遵循与命名空间相同的结构,则上述.php文件将包含以下类。

  • Tavern\Core\Activate
  • Tavern\Core\Setup
  • Tavern\View\Post
  • Tavern\View\Page

请注意,文件和文件夹名称区分大小写,并且应与命名空间和类名完全匹配。

当然,您可以自由地遵循您希望的任何约定。 但是,前面的建议是一种很好的做法,从长远来看,它将简化您组织项目的方式。

使用命名空间的好处

最明显的好处是避免了同名的类和函数之间的冲突。 出于与使用前缀相同的原因,您应该使用真正的命名空间。

命名空间有助于避免长类名。 在整个大型项目中键入长名称充其量是一种乏味的做法。

通过导入更轻松地切换实现。 一旦掌握了从其他命名空间导入类和接口的窍门,就可以用一行代码切换接口的实现。

如果您遵循 PSR-4: Autoloader 标准,则自动加载类要容易得多,该标准至少需要一个顶级命名空间。

对于专业领域的开发人员,您将获得 WordPress 生态系统之外的适销对路的技能。 如果您不知道如何使用命名空间,您将很难找到 PHP 开发工作。 这不是一个很难掌握的概念,但在实践中可能会有一些学习曲线。