如何为 PHP 8 准备 WordPress 网站

已发表: 2022-07-06

WordPress 网站需要 PHP,随着 PHP 的发展,WordPress 也跟上了。 最近,PHP 7.4 已成为 WordPress VIP 平台上的默认 PHP 版本。 然而,随着 PHP 7.4 于 2022 年 11 月结束其安全支持,WordPress 网站将需要升级以保持强大的安全性。 出于这个原因,WordPress VIP 平台将迁移我们所有的客户应用程序以在 PHP 8.0 上运行。

以下是对更改的描述,以及我们的客户和其他平台上使用 WordPress 的其他人可以做的准备步骤。

目录

  • PHP 8.0 的故事
    • 新的功能
    • 在 PHP 和 WordPress 社区中增加支持
  • 如何查找 PHP 8.0 兼容性问题
    • 将 PHP_CodeSniffer 与 PHPCompatibility 标准一起使用
    • 解决 PHP 8.0 下已知的 PHP 致命错误的 PHP 警告
    • 创建自动化测试
    • 使用 PHPStan/Psalm 或其他静态分析工具
  • 如何在 WordPress VIP 上开始使用 PHP 8.0
    • 在本地运行应用程序
    • 检查拉取请求的 VIP 代码分析机器人
    • 在您的 WordPress VIP 应用程序上启用 PHP 8
    • 利用主动帮助
  • PHP 8.1 怎么样?

PHP 8.0 的故事

PHP 8.0 于 2020 年 11 月发布,提供了多项增强功能和功能,使新代码(和更短的代码)对错误更具弹性。

大多数开发人员会在 PHP 8.0 中发现很多好处。 但是,作为主要版本,它确实包含一些重大更改。 这使得从 PHP 7.4 到 PHP 8.0 的转换比从 PHP 7.3 到 PHP 7.4 的转换更加棘手。 具体来说,核心 PHP 有 49 处重大更改,整个 PHP 8 中有 169 处更改,包括您的代码可能依赖的库和扩展。

好消息是,一旦组织迁移到 PHP 8.0,他们将在 2023 年 11 月之前从核心 PHP 项目获得安全支持。在那之后,组织将需要升级到 PHP 8.1,这是一个需要进行小得多的更改的次要版本。

新的功能

PHP 8.0 旨在 1) 修复边缘情况和不一致性,使 PHP 成为一种更可靠和可预测的脚本语言,以及 2) 提供新功能来整体改进语言。 其中包括几种新语法:

  • 更容易编写严格类型的代码,例如联合类型、 staticmixed类型、 Stringable接口以及数字处理中的更改。
  • 减少您必须维护的代码量,例如 nullsafe 运算符、构造函数属性提升、 match运算符和非捕获捕获。
  • 简化代码,例如允许对象上的::class 、参数列表中的尾随逗号、 str_contains()str_starts_with()str_ends_with()函数、抛出表达式、属性。

它还包括命名参数。 但是,值得注意的是 WordPress 核心并未声称与此功能兼容。 因此,虽然您可以使用命名参数调用自己的自定义函数,但不应调用 WordPress 函数,因为参数名称将来可能会更改而不会发出警告。

在 PHP 和 WordPress 社区中增加支持

每当发布包含新语法的新 PHP 版本时,整个 PHP 和 WordPress 社区都需要时间来支持新语法。

PHP 开发者工具

PHP 开发工具如 Composer、PHPUnit、PHP_CodeSniffer、PHPStan、Xdebug 和各种 IDE 都需要识别新版本 PHP 的新语法。 虽然 PHP 正在不断开发中,但围绕新版本的完整生态系统可用可能需要一段时间。 但是,通常,在最终版本准备就绪时,工具就可以准备就绪,因为开发工作是基于提前提供的alphabeta候选发布版本进行的。 所有这些工具以及更多工具现在都支持 PHP 8.0,这使其成为开发 PHP 代码特别是开发 WordPress 的不错选择。

WordPress核心

接下来,WordPress 核心需要支持 PHP 8.0。 WordPress 项目在新版本 PHP 发布时与它们的兼容性由来已久。 根据 Make WP 上这篇写得很好的帖子,自 2020 年 12 月发布 WordPress 5.6 以来,WordPress 与 PHP 8.0 具有“测试版兼容性”。“测试版兼容性”是什么意思? 这意味着 WordPress 可以在 PHP 8.0 上正常运行,但不支持在 WordPress 核心文件中声明严格类型或在 WordPress 核心函数中使用命名参数等功能。

WordPress VIP平台

WordPress VIP 平台自 2022 年 5 月起支持 PHP 8.0(和 PHP 8.1),包括允许平台满足企业需求的插件和功能套件。

第三方插件

WordPress 拥有数以万计的插件,并且对 PHP 8.0 的支持程度差异很大。 例如,插件可能仍会使用新的保留字,或者传递给 PHP 原生函数的参数可能不是现在预期的类型。 因此,第三方插件可能是与 PHP 8.0 的不兼容性可能影响您的应用程序的一个领域。

您可以在下面了解如何检查其中一些不兼容性。 选项包括要求上游个人/团队进行修复并发布新版本,或者让内部开发团队或代理机构(如我们的特色合作伙伴之一)分叉插件并自行修复。

自定义插件

WordPress VIP 平台上的几乎每个客户都使用一个或多个自定义插件。 与第三方插件一样,它们也需要进行兼容性检查。 要求原始开发人员解决发现的问题通常是最好的做法。

第三方或自定义主题

虽然插件是兼容性问题的最可能来源,但不要忘记第三方和自定义主题也需要与 PHP 8.0 兼容。 检查插件代码兼容性的相同方法适用于主题代码。

如何查找 PHP 8.0 兼容性问题

开发团队可以使用四种主要方法来审查代码以确定兼容性问题:

  1. 将 PHP_CodeSniffer 与 PHPCompatibility 标准一起使用。
  2. 解决 PHP 8.0 下的已知 PHP 警告,即 PHP 致命错误。
  3. 创建自动化测试。
  4. 使用 PHPStan/Psalm 或其他静态分析工具。

将 PHP_CodeSniffer 与 PHPCompatibility 标准一起使用

PHP_CodeSniffer (PHPCS) 标记 PHP 文件并检测是否违反了一组定义的编码标准。 有 WordPress 编码标准的软件包,以及我们自己的 VIP 编码标准(我们鼓励客户使用)。

还有称为 PHPCompatibility 和 PHPCompatibilityWP 的包,这些标准分析了 PHP 跨版本兼容性的代码库。

因为结果取决于工具功能和准备情况,所以必须使用 PHPCompatibility 的develop分支,直到版本 10 发布。 版本 10 将包含与 PHP 8.0(和 PHP 8.1)兼容性相关的嗅探。 有关如何设置配置以使用develop分支的说明,请参阅我们的文档。 版本 10 发布后,您可以改用该版本。

PHPCompatbilityWP 包构建在 PHPCompatibility 包之上,但对 WordPress 核心自身包含的向后兼容性项目进行了一些检查。

设置好 PHPCS 和 PHPCompatibility/PHPCompatibilityWP 后,您可以运行检查:

 phpcs --standard=PHPCompatibilityWP --severity=1 --runtime-set testVersion 8.0- --extensions=php <path-to-code>

如果您想从小处着手, <path-to-code>可以是单个自定义或第三方插件或主题,如果您想查看所有需要调查和解决的违规行为,则可以是整个存储库。

扫描步骤不会检测到所有可能的 PHP 版本兼容性问题(例如不正确的运行时值类型),但它们将有助于识别与语法相关的最常见问题。

解决 PHP 8.0 下已知的 PHP 致命错误的 PHP 警告

PHP 8.0 看到了一些重新分类的引擎警告,其中警告变成了致命错误和 TypeError 异常(并且一些通知变成了警告)。 在 PHP 7.4 下要查找的 PHP 警告文本是:

  • Attempt to assign property '*' of non-object
  • Attempt to modify property '*' of non-object
  • Attempt to increment/decrement property '*' of non-object
  • Creating default object from empty value
  • Cannot use a scalar value as an array
  • Cannot add element to the array as the next element is already occupied
  • Cannot unset offset in a non-array variable
  • Only arrays and Traversables can be unpacked
  • Invalid argument supplied for foreach()
  • Illegal offset type
  • Illegal offset type in isset or empty
  • Illegal offset type in unset
  • Cannot assign an empty string to a string offset
  • Division by zero
  • Use of undefined constant *

修复这些警告对于应用程序与 PHP 8.0 兼容至关重要。

注意:在 PHP 8.0 下还有其他致命错误,在 PHP 7.4 下甚至不是警告。 示例包括:

  • 除构造函数外,私有方法不得声明为 final。
  • 魔术方法的签名无效。
  • 抽象特征方法签名验证
  • parent::与父类一起使用。
  • 不兼容的重载方法签名(Liskov 替换原则)

解决这些已知的变化是一个很好的起点。 所有内部 PHP 函数都会持续抛出 TypeError,例如当传递了无效的参数类型时,即使没有声明严格的类型检查也是如此。

另外,请注意@运算符将不再消除 PHP 8.0 下的致命错误。

自然,您的应用程序理想情况下应该不产生错误、警告和通知。 我们鼓励您解决您发现的任何问题。 8.x 下的一些 PHP 警告将是 PHP 9.0 下的致命错误,例如,可能导致 PHP 8.x 下的逻辑不正确。 在发布前和发布后构建开发时间以解决此类问题以及在开发过程中“逃避发现”的问题是最佳实践。 这也是对网站稳定性的投资,以及准确满足相关功能的验收标准的能力。

创建自动化测试

有许多不同类型的自动化测试,但这里我们的意思是:

  • 单元测试——模拟任何 WordPress 定义的函数或类,并且不需要数据库实例即可运行测试。
  • 集成测试——加载 WordPress 并使用实际的测试数据库

这个话题太大了,无法在这里很好地涵盖,但有几点需要考虑:

  • 结果取决于测试套件的完整性。 如果您没有很多测试,那么您将缺乏必要的覆盖范围来确保兼容性。
  • 使用严格的断言。 例如,使用assertEquals()进行松散比较,而assertSame()也检查类型。
  • 使用严格的代码覆盖率。 将beStrictAboutCoversAnnotations=”true”forceCoversAnnotations=”true”添加到 PHPUnit 配置文件中,然后使用@covers注解查找跨测试的国际代码覆盖率的准确级别。
  • 测试快乐(基于预期输入的行为)和不快乐(基于意外输入的行为)路径,以确保函数以预期的方式失败,因为这是最严格相关问题发生的地方。
  • 在 PHP 8.0 上运行测试。 对于集成 (WordPress) 测试,2021 年对使用更高版本的 PHPUnit 解锁的 WordPress 核心测试套件进行了更改,后者又支持 PHP 8.0。 WP Test Utils 包支持这一点,其中包括 PHPUnit Polyfills、Brain Monkey 和 Mockery 支持、WordPress 函数的附加函数存根,以及对所有 WP 原生测试实用程序(如用于内容创建的工厂方法)的访问。
  • 考虑在尝试修复之前编写测试,以更加确信兼容性更改已成功。

使用 PHPStan/Psalm 或其他静态分析工具

虽然 PHPCS 会捕获一些不兼容性,但 PHPCS 并非旨在捕获一些运行时更改。 一个可能会被忽略的例子是原生 PHP 函数对可以作为参数传递的类型更加严格。

PHPStan、Psalm 等工具或其他静态分析工具可以提供帮助。 但是,为了最有效,它们要求您的代码库要么使用严格类型(代码中的参数和返回类型),要么正确记录(DocBlocks 中的@param@return行)。

这些工具通常具有允许首先修复最低级别问题的规则级别,然后逐渐进一步集成该工具以提高代码库的质量。

您可以通过 phpstan-wordpress 和 psalm-plugin-wordpress 等扩展为 WordPress 核心代码添加类型知识。

配置后,每次运行都会突出显示您将意外类型传递给函数的位置,这可能会导致抛出致命的 TypeError 异常。 这些中的每一个都需要修复。

在许多情况下,您可以通过使用 try-catch 块或类型转换来抑制 TypeError 异常。 但是,我们强烈建议您不要这样做。 解决根本原因将导致代码更强大、更不脆弱和更容易出错,并且从长远来看几乎总能得到回报。

如何在 WordPress VIP 上开始使用 PHP 8.0

在本地运行应用程序

在本地运行应用程序实例是能够检测和修复任何兼容性问题的明智的第一步。 虽然您可以使用任何本地开发环境,但为了确保与 WordPress VIP 平台的最佳对等性,我们推荐 VIP 本地开发环境。 通过运行命令vip dev-env create --php=8.0 (使用 VIP-CLI 2.9.5 或更高版本)然后完成设置向导的其余部分,您的应用程序将使用 PHP 8.0 在本地运行。

检查拉取请求的 VIP 代码分析机器人

如果您查看在 wpcomvip 组织下对您的存储库发出的任何拉取请求,您将看到 VIP 代码分析机器人为您提供有关 PHPCS、PHP linting 和 SVG linting 的反馈。

对于 PHP Linting 步骤,机器人将使用用于部署存储库的应用程序的任何 PHP 版本对 PHP 代码进行 lint。 如果该版本是 PHP 7.4,它现在也将自动使用 PHP 8.0 进行 lint,为即将到来的切换做准备。

在您的 WordPress VIP 应用程序上启用 PHP 8

一旦您在本地完成了尽可能多的检查和修复,就可以在您的 WordPress VIP 应用程序上启用 PHP 8.0。 从您的最低环境开始,并在升级到生产环境之前检查一切是否正常(包括通过 vip-cli 的 PHP 日志或 VIP 仪表板中的健康日志)。

要在环境中启用 PHP 8.0,请打开 Zendesk 票证,让我们知道您希望在哪个应用程序和环境上启用它。

我们很快将在 VIP 仪表板上发布一项新功能,以允许更改 PHP 版本而无需打开工单。 随时查看大厅以获取最新信息。

利用主动帮助

Premier 客户的客户团队已经与客户联系,讨论我们如何为他们提供支持。 他们将从 PHPCS 收到结果,并提供有关如何自行运行这些检查的指导。 将成为致命错误的 PHP 警告也将被突出显示,让它们在解决不兼容性方面领先一步。

PHP 8.1 怎么样?

WordPress VIP 平台也支持 PHP 8.1。 PHP 8.0 和 PHP 8.1 之间的更改比 PHP 7.4 和 8.0 之间的更改要少,这意味着要解决的不兼容性应该更少。

PHP 8.1:

  • 在 2023 年 11 月之前获得 PHP 核心开发人员的积极支持,在 2024 年 11 月之前获得安全支持。
  • 每秒可以处理比 PHP 8.0 更多的请求。
  • 在 WordPress 5.9 及更高版本上具有“beta 兼容性”支持——这意味着在准备 PHP 9 时有一些弃用通知,但不会影响 WordPress 核心的行为。

PHP 8.0 所需的有用更改(例如使用严格类型化的代码和添加自动化测试)将有助于 PHP 8.1 的推出,以及 WordPress 6.1、6.2、6.3 及更高版本的升级,以及您所做的任何功能发布。 QA 流程通常是瓶颈,因此使用我们概述的一些工具和方法可以减少手工劳动并让您在部署这些更改时更有信心。

如果客户对 PHP 8.0 有任何疑问,请向我们开票。