PHP7转PHP8代码需要做哪些修改?

踩坑教训·php·编程语言 · 2023-07-25

在将 ·PHP 7· 代码转换为 PHP 8 时,可能需要做出一些修改,因为 PHP 8 引入了一些新特性并删除了一些过时的特性。以下是可能需要修改的一些方面:

声明严格模式:PHP 8 强制实施了类型声明,因此需要在 PHP 7 代码中进行相应修改,添加类型声明。可以使用 declare(strict_types=1); 声明严格模式,强制要求在函数和方法中进行类型声明。

面向对象编程:PHP 8 引入了一些新的面向对象编程特性,如构造函数属性推断、命名参数和属性提取等。如果使用了这些新特性,需要进行相应修改。

函数调用:PHP 8 修改了一些函数的参数,可能需要根据新的参数列表进行修改。例如,array_key_first()array_key_last() 函数需要一个数组参数,而在 PHP 7 中不需要。

错误处理:PHP 8 改变了一些错误处理方式,如对于未声明变量的引用,现在会抛出一个 Error 异常而不是一个 Notice 错误。因此,需要相应地处理这些错误。

移除过时的特性:PHP 8 移除了一些过时的特性,如 create_function() 函数和 magic_quotes_gpc 配置选项等。需要检查代码中是否使用了这些过时的特性,并进行相应的修改。

以上是可能需要修改的一些方面,具体需要根据代码的实际情况进行修改。可以使用 PHP 官方提供的迁移工具来辅助进行代码迁移,例如 php-src/UPGRADING 文件和 php-compat-info 工具。

php-src/UPGRADINGphp-compat-info

以下是使用 php-src/UPGRADING 文件和 php-compat-info 工具进行 PHP 7 代码转换为 PHP 8 的步骤:

下载 php-src/UPGRADING 文件:可以从 PHP 官方网站下载 php-src/UPGRADING 文件,该文件包含了从 PHP 7PHP 8 的所有重大变化和不兼容之处。

使用 php-compat-info 工具:php-compat-info 工具是一个命令行工具,可以分析代码库中使用的 PHP 版本和扩展,并生成有关 PHP 7PHP 8 转换的报告。

检查报告:根据 php-compat-info 工具生成的报告,检查代码库中使用的 PHP 版本和扩展,并查找需要修改的部分。报告中将显示需要修改的代码行以及建议的修改方法。

进行修改:根据报告中的建议,对代码进行相应的修改。修改后,可以再次使用 php-compat-info 工具进行检查,确保代码与 PHP 8 兼容。

尽管 php-compat-info 工具可以帮助分析代码并提供有用的建议,但它并不能处理所有情况。因此,在进行代码转换时,建议仔细阅读 php-src/UPGRADING 文件和 PHP 官方文档,以确保代码的兼容性和正确性。此外,建议进行逐步转换,先进行部分功能的测试和修改,而不是一次性修改整个代码库。这样可以更好地控制风险,避免潜在的问题。

PHP8对函数参数列表的修改

PHP 8 对一些函数的参数列表进行了修改,以下是一些常见的函数和它们在 PHP 8 中的参数列表变化:

  • implode() 函数的参数顺序变化,将 glue 参数放在第一位,将 pieces 参数放在第二位。PHP 7 参数列表:implode($glue, $pieces) PHP 8 参数列表:implode($pieces, $glue = '')
  • array_key_first()array_key_last() 函数需要传入一个数组参数。PHP 7 参数列表:array_key_first($array)、array_key_last($array) PHP 8参数列表:array_key_first(array $array)、array_key_last(array $array)
  • str_starts_with()str_ends_with() 函数需要传入一个字符串参数。PHP 7 参数列表:str_starts_with($haystack, $needle)、str_ends_with($haystack, $needle) PHP 8 参数列表:str_starts_with(string $haystack, string $needle)、str_ends_with(string $haystack, string $needle)
  • (mb_strimwidth() 函数将 start 参数改名为 startpos。PHP 7 参数列表:mb_strimwidth($str, $start, $width, $trimmarker = '', $encoding = mb_internal_encoding()). PHP 8 参数列表:mb_strimwidth(string $str, int $startpos, int $width, string $trimmarker = '', string $encoding = mb_internal_encoding())

以上仅列举了一些常见的函数,还有其他函数的参数列表也可能发生变化。在进行 PHP 7 到 PHP 8 的代码升级时,需要仔细查阅官方文档和 php-src/UPGRADING 文件,以确保代码的正确性和兼容性。

严格模式

PHP 8 引入了声明严格模式(strict mode),它是一种更加严格的类型检查模式,可以让开发者在开发过程中更加安全、可靠地编写 PHP 代码。

在声明严格模式下,PHP 将会对类型和变量使用更加严格的检查,包括以下几个方面:

类型声明在声明严格模式下,函数和方法的参数类型必须与声明的类型相匹配。如果类型不匹配,PHP 会抛出一个致命错误。

示例:

declare(strict_types=1);
 
function sum(int $a, int $b) {
    return $a + $b;
}
 
echo sum(1, 2); // 输出 3
echo sum(1.5, 2); // 报错:Uncaught TypeError

返回类型声明在声明严格模式下,函数和方法的返回值类型必须与声明的类型相匹配。如果类型不匹配,PHP 会抛出一个致命错误。

示例:

declare(strict_types=1);
 
function divide(int $a, int $b): float {
    return $a / $b;
}
 
echo divide(6, 2); // 输出 3.0
echo divide(6, 0); // 报错:Uncaught TypeError

类型推导在声明严格模式下,PHP 会自动推导一些变量的类型。如果推导出来的类型与声明的类型不匹配,PHP 会抛出一个致命错误。

示例:

declare(strict_types=1);
 
function multiply(int $a, int $b) {
    $result = $a * $b;
    return $result;
}
 
echo multiply(2, 3); // 输出 6
echo multiply("2", 3); // 报错:Uncaught TypeError

需要注意的是,声明严格模式需要在文件的开头通过 declare(strict_types=1) 声明启用。如果未启用声明严格模式,则 PHP 会采用弱类型检查模式,允许一些类型的自动转换。

命名参数

PHP 8 引入了命名参数(named parameters)功能,它可以让我们通过参数名来传递函数和方法的参数,而不必按照原始函数定义的参数顺序传递参数。

在 PHP 8 中,我们可以通过在函数或方法的调用时使用 参数名 => 值 的方式来传递参数,而不必按照原始函数定义的参数顺序传递参数。这种传递参数的方式称为命名参数。

命名参数的优点包括:

更好的可读性:命名参数可以提高函数或方法调用的可读性,因为参数名称可以清晰地表明参数的作用。

更高的灵活性:通过命名参数,我们可以只传递需要的参数,而不必传递所有参数,这样可以让函数或方法更加灵活。

下面是一个简单的例子,展示了如何使用命名参数:

function createPerson(string $name, int $age, string $gender) {
    // 创建一个人员对象
}
 
// 使用命名参数调用函数
createPerson(name: "Tom", age: 18, gender: "male");

在上面的例子中,我们通过 参数名 => 值 的方式来传递函数的参数。这样可以让代码更加清晰易懂,特别是在函数参数较多时。命名参数必须在普通参数之后传递,且不能重复声明同一个参数。此外,在使用命名参数时,我们不必按照原始函数定义的参数顺序传递参数,但是必须使用参数名称来传递参数。

函数调用

PHP 8 引入了一些新的函数调用语法,包括可选链式调用、null 合并运算符的链式调用、match 表达式等。

可选链式调用:

可选链式调用是一种在调用对象方法或访问对象属性时,如果对象为 null 则不抛出异常而是返回 null 的语法糖。在 PHP 8 中,我们可以使用 ?-> 运算符来进行可选链式调用,示例如下:

// 在对象方法调用中使用可选链式调用
$result = $object?->getValue();
 
// 在对象属性访问中使用可选链式调用
$value = $object?->property;

null 合并运算符的链式调用:

null 合并运算符(??)的链式调用可以让我们在多个变量中查找非空值并返回第一个非空值。在 PHP 8 中,我们可以使用 ??= 运算符来进行 null 合并运算符的链式调用,示例如下:

// 在 null 合并运算符中使用链式调用
$result = $object->getValue() ?? $object->getValue2() ?? $default;

match 表达式:

match 表达式是一种新的语法糖,用于替代 switch 语句。在 PHP 8 中,match 表达式可以更加简洁地实现类似的功能,示例如下:

// 使用 match 表达式代替 switch 语句
$value = 5;
$result = match ($value) {
    1 => 'one',
    2 => 'two',
    3, 4 => 'three or four',
    default => 'other',
};

在上面的示例中,我们使用 match 表达式根据变量 $value 的值来匹配不同的条件,并返回对应的结果。在 match 表达式中,我们可以使用逗号将多个条件合并在一起,用于匹配相同的结果。此外,match 表达式中必须有一个 default 分支来处理无法匹配的情况。

PHP8移除的过时特性

PHP 在不同的版本中移除了很多过时的特性,以下是一些常见的被移除的特性:

  • 不再支持 ASP 风格的标记,即将 <??> 用于标记 PHP 代码的方式。这种标记在 PHP 7.4 中被移除。
  • 不再支持未赋值的函数调用,即对一个未定义的函数进行调用,这在 PHP 7.2 中被移除。
  • 不再支持传递可变数量的参数给引用参数,这在 PHP 7.3 中被移除。
  • 不再支持传递未声明的类给 instanceof 运算符,这在 PHP 8.0 中被移除。
  • 不再支持使用被废弃的错误控制运算符 @,这在 PHP 8.0 中被移除。
  • 不再支持使用被废弃的 each() 函数,这在 PHP 7.2 中被移除。
  • 不再支持使用被废弃的 create_function() 函数,这在 PHP 7.2 中被移除。
  • 不再支持使用被废弃的 mbstringiconv 扩展中的一些函数,例如 mb_ereg_replace()iconv_set_encoding() 等。

在进行 PHP 版本升级时,需要仔细查阅官方文档和 php-src/UPGRADING 文件,以确保代码的正确性和兼容性。

str_contains()str_starts_with() 函数

PHP 8 新增了两个字符串函数 str_contains()str_starts_with(),用于判断一个字符串是否包含另一个字符串或者以另一个字符串开头。如果要适配这两个函数,可以按照以下方式使用:

str_contains() 函数该函数用于判断一个字符串是否包含另一个字符串,如果包含则返回 true,否则返回 false。它的参数列表如下:

bool str_contains(string $haystack, string $needle)

其中,$haystack 表示要搜索的字符串,$needle 表示要查找的子字符串。

示例:

$string = "hello world";
if (str_contains($string, "world")) {
    echo "包含";
} else {
    echo "不包含";
}

输出:

包含
str_starts_with() 函数该函数用于判断一个字符串是否以另一个字符串开头,如果是则返回 true,否则返回 false。它的参数列表如下:

bool str_starts_with(string $haystack, string $needle)

其中,$haystack 表示要搜索的字符串,$needle 表示要查找的前缀字符串。

示例:

$string = "hello world";
if (str_starts_with($string, "hello")) {
    echo "以 hello 开头";
} else {
    echo "不以 hello 开头";
}

输出:

hello 开头
这两个函数仅在 PHP 8 中才可用,如果在 PHP 7 或更早的版本中使用,会导致语法错误。如果要在旧版本的 PHP 中使用类似的功能,可以使用其他函数或者手动实现。

php
Theme Jasmine by Kent Liao