Notice: 函数 WP_Object_Cache::add 的调用方法不正确。 缓存键不能为空字符串。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.1.0 版本添加的。) in /www/wwwroot/zz2zz.com/wp-includes/functions.php on line 6078
广告投放

跨版本PHP代码转换终极教程

跨版本PHP代码转换终极教程跨版本PHP代码转换终极教程

在理想情况下,我们应该为我们的所有网站使用PHP8.0(撰写本文时的最新版本),并在新版本发布后立即进行更新。但是,开发人员通常需要使用以前的PHP版本,例如为WordPress创建公共插件或使用妨碍升级Web服务器环境的遗留代码时。

在这种情况下,我们可能会放弃使用最新PHP代码的希望。但是还有一个更好的选择:我们仍然可以使用PHP8.0编写源代码,并将其转换到以前的PHP版本,甚至是PHP7.1。

在本指南中,我们将教您有关转换PHP代码的所有知识。

  1. 什么是Transpiling?
  2. Transpiling PHP的优势
  3. PHP转换器(PHP Transpilers)
  4. 转换到哪一个PHP版本
  5. Transpiling vs Backporting
  6. Transpiled PHP示例
  7. 转换PHP的利弊
  8. 如何转换PHP
  9. 优化转换过程
  10. 转换代码时要避免的坑
  11. 转换和连续集成
  12. 测试转换代码

什么是Transpiling?

Transpiling将源代码从编程语言转换为相同或不同编程语言的等效源代码。

Transpiling并不是Web开发中的一个新概念:客户端开发人员很可能熟悉Babel,JavaScript代码的转换器。

Babel将现代ECMAScript 2015+版本中的JavaScript代码转换为与旧浏览器兼容的旧版本。例如,给定ES2015箭头函数:

[2, 4, 6].map((n) => n * 2);

…Babel将其转换为ES5版本:

[2, 4, 6].map(function(n) {
  return n * 2;
});

什么是Transpiling PHP?

Web开发中潜在的新功能是转换服务器端代码的可能性,特别是PHP。

转换PHP的工作方式与转换JavaScript的工作方式相同:现代PHP版本的源代码转换为旧PHP版本的等效代码。

下面是与前面相同的示例,PHP 7.4中的箭头函数:

$nums = array_map(fn($n) => $n * 2, [2, 4, 6]);

…可以转换为其等效的PHP 7.3版本:

$nums = array_map(
  function ($n) {
    return $n * 2;  
  },
  [2, 4, 6]
);

可以转换箭头函数,因为它们是语法糖,即生成现有行为的新语法。这是低垂的果实。

然而,也有一些新特性创建了一种新的行为,因此,对于以前版本的PHP不会有等效的代码。PHP 8.0中引入的联合类型就是这样:

function someFunction(float|int $param): string|float|int|null
{
  // ...
}

在这些情况下,只要开发需要新特性,而不是生产需要新特性,就仍然可以进行转换。然后,我们可以简单地从转换的代码中完全删除该特性,而不会产生严重后果。

联合类型就是这样一个例子。此功能用于检查输入类型与其提供的值之间是否不匹配,这有助于防止错误。如果与类型发生冲突,那么开发中就会出现错误,我们应该在代码到达生产环境之前捕获并修复它。

因此,我们可以从生产代码中删除该功能:

function someFunction($param)
{
  // ...
}

如果错误仍然发生在生产中,抛出的错误消息将不如使用联合类型时准确。然而,这一潜在的缺点被能够首先使用联合类型所抵消。

Transpiling PHP的优势

Transpiling使您能够使用最新版本的PHP编写应用程序,并生成一个在运行旧版本PHP的环境中也能工作的版本。

这对于为旧式内容管理系统(CMS)创建产品的开发人员特别有用。例如,WordPress仍然官方支持PHP5.6(尽管它推荐PHP7.4+)。运行PHP版本5.6到7.2的WordPress站点的百分比为34.8%,而运行PHP版本(8.0除外)的站点的百分比高达99.5%:

跨版本PHP代码转换终极教程跨版本PHP代码转换终极教程

WordPress使用情况统计(按版本)图像来源:WordPress

因此,面向全球受众的WordPress主题和插件很可能使用旧版本的PHP进行编码,以增加其可能的影响范围。多亏了transpiling,这些代码可以使用PHP8.0进行编码,并且仍然可以针对较旧的PHP版本发布,从而尽可能多地面向用户。

事实上,任何需要支持除最新版本以外的任何PHP版本(即使在当前支持的PHP版本范围内)的应用程序都可以从中受益。

Drupal就是这样,它需要PHP7.3。由于transpiling,开发人员可以使用PHP8.0创建公开可用的Drupal模块,并使用PHP7.3发布它们。

另一个例子是为由于某种原因而无法在其环境中运行PHP8.0的客户机创建自定义代码时。尽管如此,多亏了transpiling,开发人员仍然可以使用PHP8.0编写可交付成果,并在这些遗留环境中运行它们。

何时需要转换PHP(Transpile PHP)

PHP代码始终可以转换,除非它包含一些在之前的PHP版本中没有对等的PHP功能。

情况可能就是这样属性,在PHP 8.0中介绍:

#[SomeAttr]
function someFunc() {}

#[AnotherAttr]
class SomeClass {}

在前面使用箭头函数的示例中,可以转换代码,因为箭头函数是语法糖。相反,属性创建了全新的行为。PHP7.4及以下版本也可以复制这种行为,但只能通过手动编码,即不自动基于工具或流程(AI可以提供解决方案,但我们还没有)。

用于开发的属性,如#[Deprecated],可以用删除联合类型的相同方式删除。但是,不能删除在生产中修改应用程序行为的属性,也不能直接转换这些属性。

到目前为止,没有一个transpiler能够接受具有PHP8.0属性的代码并自动生成其等效PHP7.4代码。因此,如果您的PHP代码需要使用属性,那么转换它将是困难的或不可行的。

可转换PHP功能

这些是PHP7.1及以上版本的特性,目前可以转换。如果您的代码只使用这些特性,那么您可以确信您的转换应用程序将正常工作。否则,您将需要评估转换的代码是否会产生故障。

PHP 版本 特征
7.1 所有都可以
7.2 – object type
– parameter type widening
– PREG_UNMATCHED_AS_NULL flag in preg_match
7.3 – Reference assignments in list() / array destructuring (Except inside foreach — #4376)
– Flexible Heredoc and Nowdoc syntax
– Trailing commas in functions calls
– set(raw)cookie accepts $option argument
7.4 – Typed properties
– Arrow functions
– Null coalescing assignment operator
– Unpacking inside arrays
– Numeric literal separator
– strip_tags() with array of tag names
– covariant return types and contravariant param types
8.0 – Union types
– 
mixed pseudo type
– 
static return type
– 
::class magic constant on objects
– 
match expressions
– 
catch exceptions only by type
– 
Null-safe operator
– 
Class constructor property promotion
– 
Trailing commas in parameter lists and closure use lists

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
广告位招租919838898
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索