作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
安德烈·沙拉索夫的头像

By 安德烈Shalashov

Andrey是一名全栈web开发人员和WordPress专家. 最近,他专注于无服务器计算和JAMstack.

专业知识

工作经验

12

分享

WordPress 它是世界上使用最广泛的网站技术吗. 然而,遗留代码的核心是一团乱码,这个问题会波及到第三方开发人员. 一些开发人员以此为借口,在自己的WordPress PHP代码中偷工减料, 但是,从长远来看,这种方法的成本更高,除了最微不足道的更改.

In 第1部分 我们关于WordPress编程的两部分系列的第一部分, 我们专注于整体项目和工作流工具, 其次是前端开发. 现在是时候迎难而上,与PHP (WordPress编码语言)较量了. 具体来说,就是如何在处理后端WordPress代码时遵循最佳实践. 您可能会认为这是一个PHP/WordPress后端教程, 但是更高级一点, 假设您已经完成了一些WordPress后端开发和定制.

So, 哪些现代软件设计原则和PHP特性将为您的时间提供最佳价值? 以下是我强烈推荐的10个WordPress和PHP开发实践.

现代WordPress开发最佳实践#1:遵循“关注点分离”

关注点分离 意味着具有不同功能或目的的部分WordPress PHP代码不应该混合在一起. 而不是, 它们应该被组织成不同的部分或模块, 通过定义的接口相互传递数据. (An 接口 是模块作为输入的一组已定义的参数,以及它输出的是什么.与之密切相关的术语是 单一责任原则每个代码模块(或函数)应该只负责一件事.

遵循这些原则的最终目标是生成模块化的代码, 因此是可维护的, 可扩展的, 和可重用.

这可真拗口, 让我们看一个WordPress PHP的例子(来自WordPress核心),它把所有的东西都缠在一起. 这种风格的编码通常被称为“意大利面条代码”,因为理解其内部工作原理几乎是不可能的. 的 excerpt below was redacted for brevity; however, the 原始 保留了样式和格式.

$id = isset($ _REQUEST['id']) ? interval ($ _REQUEST['id']): 0;
get_blog_prefix( $id );
    $sql = "SELECT * FROM {$blog_prefix}选项
        WHERE option_name NOT LIKE %s
        AND option_name NOT LIKE %s";
    $query       = $wpdb->prepare(
        sql,美元
        $wpdb->esc_like( '_' ) . '%',
        '%' . $wpdb->esc_like( '使用r_roles' )
    );
    $options     = $wpdb->get_results( $query );
    Foreach ($options作为$option) {
        if ( strpos( $option->option_value, "\n" ) === false ) {
            ?>
            option_name, array( 'siteurl', 'home' ) ) ) { ?>
                

首先,这是完全不可理解的. 我喜欢唯一的评论是 foreach结束,这完全是多余的. 我们有数据库查询, 查询结果处理, 嵌入在HTML中的附加处理(有一个 if/其他的 (如果您没有注意到的话)、输出转义和HTML模板都混在一起. 另一个问题是 $id 参数直接来自全局 $ _REQUEST 而不是将实际参数传递给函数.

看看这个, 这完全可以理解为什么WordPress核心多年来基本保持不变. 重构这类代码——尤其是在维护现有行为的同时——是一项真正的史诗级任务,没有人愿意这样做.

那么我们如何正确地做呢? 好吧,有一件事要记住,没有人 真正的 道路。. 我们上面提到了我们应该争取的品质:我们需要WordPress自定义PHP代码易于维护和模块化. 让我们看看如何将上面的代码分割成模块.

  • 显然,SQL查询应该在单独的模块中. WordPress已经有一个很好的抽象 WP_Query 类,该类应用作示例.
  • 所有的HTML都放入一个模板中. 我们将在下面进一步介绍PHP模板.
  • 其余的PHP代码应该包装在一个函数中——如果代码太长或太复杂,那么应该包装在几个函数中. 参数如下 $id 是通过函数参数传递的吗.

这是上面例子的一个极大简化的重写:

函数betterSiteSettings (args)美元
{
    $data = WP_Settings_Query($args);
    //处理$data
    $context = array_merge([], $data_processed, $other_data);
    返回模板:渲染(“模板.名称的上下文美元);
}

现代WordPress开发最佳实践#2:避免全局变量

WordPress有太多的全局变量. 为什么全局变量不好? 它们使您的WordPress PHP代码难以遵循,并使应用程序状态不可靠. 任何一段PHP代码——这意味着安装在wordpress中的任何插件——都可以读写全局变量, 因此,不能保证它们包含有效的数据. 试图理解全局变量在诸如 循环 是不是一项微不足道的任务.

让我们从实际的角度来看这个问题. 这个例子来自 WooCommerce. 可能每个WordPress开发者都知道它是什么——循环:




上面的代码片段呈现了一个产品模板. 在没有传递参数的情况下,它如何知道要显示哪个产品 wc_get_template_part? 看着 template,我们看到它开始于 美元的全球产品;,这就是当前产品对象的存储位置.

现在假设我们有一个搜索和过滤产品的目录页面, 我们想要显示一个“产品详细信息”弹出,而保持在同一页面. 在幕后,前端脚本执行一个AJAX请求来获取特定的产品模板. 我们不能简单地打电话 wc_get_template_part(“内容”、“单一产品”) 因为它不使用参数,所以我们需要设置几个全局变量来让它工作.

更复杂的用例将涉及多个模板, 在这些模板中触发的钩子, 第三方插件将它们的回调函数添加到这些钩子中. 它会迅速升级. 我们无法知道这些回调所依赖的全局状态. 第三方插件可以自由修改其回调中的任何全局变量. 而不是使用系统, 我们开始与体制抗争, 遇到来自不可靠全局状态的奇怪bug.

将该产品ID作为参数传递不是更明智吗? 然后我们可以重用这个模板,而不用担心搞乱WordPress使用的全局变量.

现代WordPress开发最佳实践#3:使用面向对象编程(OOP)

模块化导致了对象和面向对象编程的概念. 在最基本的层次上,OOP是一种组织代码的方式. 函数和变量被捆绑到类中并被调用 类方法属性 分别. WordPress插件手册 建议使用OOP 用于组织WordPress自定义PHP代码.

OOP中与WordPress编程相关的一个重要原则是限制对方法和属性的访问——或者用PHP的术语来说, 将它们记为 私人 or 受保护的-因此只有其他类方法可以访问和更改它们. 一个面向对象的术语是 封装:数据封装在类中, 更改该数据的唯一方法是使用提供的类方法.

这使得调试和维护代码比使用全局变量时容易得多,全局变量可以在整个代码库的任何地方修改. 考虑全局WordPress 帖子 变量. 您可以在代码中的任何地方访问它,并且许多功能都依赖于使用它. 如果你可以只修改WordPress的核心功能会怎么样呢, 但是任何人都可以阅读? 隐藏或封装全局变量 帖子 变量并围绕它构建接口将使这成为可能.

这只是对OOP的一个非常基本的描述,以及它如何在现代WordPress开发中使用. 为了进一步学习,我强烈推荐卡尔·亚历山大的电子书, 发现使用WordPress的面向对象编程,其中有关于WordPress中OOP主题的最全面和有用的内容.

重要的是要记住,OOP不是灵丹妙药:使用OOP可以像使用任何其他编程范式一样轻松编写糟糕的代码.


让我们深入了解一些关于使用PHP进行WordPress开发的具体建议.

现代PHP最佳实践#1:瞄准PHP 7.0+

使用现代PHP特性需要一个现代版本的PHP. 没有理由支持低于7的PHP版本.0. 甚至WordPress核心也需要PHP 7.早在 2019年底.

不过, 检查您的最低版本以避免在不兼容的环境中出现“白屏死机”是一个很好的做法. 下面的代码片段显示了在代码中使用插件头声明带有保护条件的最小PHP版本.

现代PHP最佳实践#2:采用PHP行业标准(PSR-2编码风格指南)

PSRs是由 PHP框架互操作组. 它们是任何现代PHP工作流中事实上的行业标准, 可以肯定地说,PHP社区作为一个整体遵循这些标准. PSR-2是描述编码风格的建议. 流行的PHP框架如Symfony和Laravel都遵循PSR-2.

为什么要使用PSR-2而不是WordPress编码标准? 主要是因为WordPress标准过时了,没有使用任何新的语言特性. 这是可以理解的,因为WordPress核心必须遵循自己的标准. 它必须支持PHP 5.直到最近PSR-2才与PHP 5兼容.2.

这可能并不明显, 但没有要求使用WordPress编码标准,除非你致力于核心. 提交一个遵循PSR-2标准的插件到WordPress插件目录是没有问题的. 事实上,有一些 非常好的论点 因为这样做.

现代PHP最佳实践#3:使用PHP模板引擎

PHP不是一个模板引擎. 一开始是一个, 但后来演变成一种功能齐全的编程语言, 没有理由继续将其用于模板化. 两个最流行的PHP模板引擎是 嫩枝叶片,分别由Symfony和Laravel使用. This article is going to 使用 嫩枝 as an example templating engine; however, 叶片具有类似的特性和功能. 我恳请你两者都考虑一下,然后自己决定哪个最适合你.

下面的例子比较了一个PHP模板和它对应的嫩枝模板. 在PHP示例中,显示和转义输出特别冗长:

Foreach ($options作为$option) {
    ?>
    

在嫩枝中,这更简洁易读:

{选项%中选项的%}
    
{% endfor %}

嫩枝的主要优点是:

  • 可读和简洁的语法
  • 自动输出转义
  • 通过继承和块扩展模板

性能方面,嫩枝可以编译成PHP模板,几乎没有任何开销. 嫩枝只有一个PHP语言结构的子集,仅限于模板. 这迫使开发人员从模板中删除业务逻辑, 这样就加强了关注点的分离.

甚至还有WordPress的嫩枝. 它被称为 木材,这是开始创建更好的模板的好方法. 的 木材启动主题 是一个用面向对象的方式组织主题的完美例子.

现代PHP最佳实践#4:使用作曲家

作曲家 是PHP的依赖管理器. 它是一个允许声明项目正在使用的库的工具, 然后自动下载, 安装, 和更新. 然后,您只需要包含作曲家的自动加载文件 供应商/自动装载.php 而不是手动要求每个库.

WordPress插件和主题通常不使用任何第三方库. 这部分是因为WordPress有一个广泛的API,几乎可以满足任何需求, 部分原因是可能的版本冲突. 考虑两个需要相同PHP库但不同版本的插件. 首先运行的插件获得正确的版本,第二个插件也获得该版本. 这很可能是另一种白屏死机的情况.

为了避免冲突,应该在应用程序级别使用依赖管理,即.e.,作为一个整体的WordPress网站. 这就是《欧博体育app下载》(更确切地说是《欧博体育app下载》)所做的. 在包(插件或主题)级别使用时, 当使用第三方库时,作曲家可能会导致冲突. 这是一个 已知的 问题. 目前存在的唯一解决方案是将外部库的名称空间重命名为唯一的名称空间, 和 这不是一项微不足道的任务.

不过,作曲家仍然有一个用途:自动加载您自己的类. 但是,在进一步了解自动加载之前,我们需要快速了解PHP名称空间.

现代PHP最佳实践#5:使用名称空间

WordPress核心是一个遗留项目, 它使用全局命名空间或, 说不同, 根本没有名称空间. 全局声明的任何类或函数(意思是不在另一个类或函数中)在整个代码库的任何地方都是可见的. 它们的名称必须是唯一的,不仅在你的代码库中,而且对于现在使用或将来可能使用的所有插件和主题.

命名冲突(e).g., 使用已经存在的名称声明函数通常会导致白屏死机, 我们不希望那样. WordPress Codex建议用一些独特的前缀为所有的函数和类命名. 而不是简单的类名 订单,我们得到 Akrte_Awesome_Plugin_订单 “Akrte”是我刚刚编的唯一前缀.

可以将名称空间视为组或文件夹, 如果我们使用文件系统的类比——这有助于组织代码和避免名称冲突. 可以使用斜杠分隔复杂的名称空间,就像嵌套文件夹一样. (PHP名称空间使用反斜杠 特别是.)

这些命名空间部分称为子命名空间. 我们的示例类 Akrte_Awesome_Plugin_订单Akrte \ Awesome_Plugin \秩序 如果使用名称空间完成. 在这里 AkrteAwesome_Plugin 名称空间部分(或子名称空间)和 订单 是类名. 然后加上a 使用 语句,然后只使用类名. 看起来确实好多了:

使用Akrte \ Awesome_Plugin \秩序;

$a = new 订单;

很明显, namespaces should be unique; thus, 我们应该给第一个“根”子命名空间一个唯一的名字, 这通常是一个供应商的名字. 举个例子,WooCommerce类 WC_REST_订单_Notes_V2_Controller 可以用这样的命名空间重新完成:

名称空间WooCommerce \ RestApi \ V2 \控制器;
类订单Notes {}

的 WooCommerce codebase does nowadays 使用 namespaces; for example, in the WooCommerce REST API版本4.

现代PHP最佳实践#6:使用自动加载器

在大多数PHP工作流中,将PHP文件链接在一起的常用方法是使用 需要 or 包括 语句. 随着项目的发展,你会得到几十个 需要 语句在主插件文件中. 自动加载器只在需要时自动包含文件. 严格来说,它是一个函数 需要当在代码中第一次遇到一个类或函数时,它是一个包含该类或函数的文件. 不需要添加任何 需要 不再手动执行语句.

由于自动加载器只加载特定请求中使用的模块,因此通常还会显著提高性能. 没有自动装弹机, 您的整个代码库被包括在内,即使一个请求只使用, 说, 10%的代码.

自动加载器函数需要知道你的类和函数驻留在哪个文件中. 有一个PHP-FIG标准, PSR-4为此,.

它表示名称空间的一部分,即前缀,被指定为对应于基本文件夹. 它后面的子名称空间对应于基本文件夹中的文件夹. 最后,类名对应于文件名. 一个示例类 Akrte \ AwesomePlugin \模型\秩序 需要下面的文件夹结构:

/ awesome-plugin
    awesome-plugin.php
    /包括
        /模型
            订单.php

名称空间前缀 Akrte \ AwesomePlugin \ 对应于 包括 在下面讨论的自动加载器配置中指定的文件夹. 模型 子命名空间有对应的 模型 文件夹,以及 订单 类包含在 订单.php.

幸运的是,不需要自己实现自动加载器函数. 作曲家可以为你创建一个自动加载器:

  1. 安装的作曲家
  2. 创建一个 作曲家.json 文件在项目的根文件夹中. 它应该包含这些行:
{
    “名称”:“商家名称/插件名称”,
    “要求”:{},
    "自动装载":{
        " psr-4 ": {
            “Akrte \ \ AwesomePlugin \ \”:“包括/”
        }
    }
}
  1. 运行 作曲家安装.
  2. 包括 供应商/自动装载.php 在你的主插件PHP文件的顶部,像这样:
    

除了名称空间,WooCommerce最新的代码库还使用了 作曲家自动装卸机.


了解了这些PHP设计原则之后, 是时候将我们所有的PHP课程与WordPress后端定制联系起来了,最后给出一个建议.

现代WordPress开发最佳实践#4:考虑使用根堆栈

最全面的现代WordPress开发流程 有. 然而,我想说的是,它不一定要用在 每一个 WordPress项目,因为:

  • 必须从一开始就使用根. 这是最常见的原因. 重构现有项目的成本太高.
  • 这是固执己见. 同意是好事,不同意是坏事. 例如,您可能更喜欢其他组织主题的方式. 固执己见的项目也需要时间来学习“他们的方式”.”
  • 不是每个人都知道. 在你之后维护你用根栈构建的站点的开发人员可能不知道它是什么,并且想知道WordPress文件夹发生了什么. 我们应该为我们的同胞着想 WordPress的开发者.

在一般情况下, 在使用任何固执己见的项目之前,您可能希望完全了解它的所有优点和缺点.

现代PHP和软件原理:使WordPress后端开发健壮

很明显,没有人 真正的 软件编写方式. 的概念, 比如关注点分离, are decades old; however, 它的实际含义一直存在争议. 以CSS为例. 一开始,我们将它内联为 style 在HTML中,然后我们决定使用单独的CSS表来实现关注点分离.

快进十年:今天的JavaScript应用程序使用 组件 作为关注点分离实现. 前端开发人员倾向于CSS-in-JS, 这基本上意味着再次在HTML中内联CSS(好吧, 事情没那么简单, 但你懂的。). 圆完成了!

最佳实践始终是关于改善开发人员体验的:

程序必须是为人们阅读而编写的,只是偶然为机器执行而编写的.

阿贝尔森 & 苏斯曼, 计算机程序的结构和解释

本PHP WordPress教程中的一些实践可以在您的项目中快速轻松地实现. 例如,自动加载器:每个项目只做一次,然后享受. 另一方面, 新的软件架构思想需要时间, 实践, 以及大量的迭代,以方便和舒适. 不过,回报要大得多. 你不仅会更有效率,而且会更享受你所做的事情. 而定期享受你为客户所做的工作,也许是唯一可以持续下去的方式.

了解基本知识

  • 你会在WordPress中使用PHP吗?

    WordPress是使用PHP作为编程语言编写的. 如果你想为WordPress开发,你当然可以使用PHP,但你不必这样做.

  • PHP在WordPress中的用途是什么?

    PHP是大多数WordPress代码库使用的编程语言. 其他使用的语言和技术包括JavaScript、CSS和HTML.

  • 如何在WordPress中编辑PHP?

    PHP可以使用任何文本编辑器编辑,因为PHP文件只是一个纯文本文件. 然而, 正确的方法是使用专门的代码编辑器和版本控制代码库.

  • 我应该先学PHP再学WordPress吗?

    WordPress是一个简单易用的CMS. 为了使用WordPress建立和运行自己的网站,你根本不需要学习编码. 大多数人把编程交给专业人员,就像你把给汽车换油交给机械师一样.

聘请Toptal这方面的专家.
现在雇佣
安德烈·沙拉索夫的头像
安德烈Shalashov

位于 爱沙尼亚塔林

成员自 2017年8月11日

作者简介

Andrey是一名全栈web开发人员和WordPress专家. 最近,他专注于无服务器计算和JAMstack.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

工作经验

12

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

加入总冠军® 社区.

option_value ); ?> />