PHP 8.0兼容性注意事项

一、前言

以下内容主要针对从PHP 7.0或更早版本跨大版本升级到PHP 8.0的开发者。

在浏览本文之前,建议阅读以下链接:

(A)官方的PHP 8.0发布介绍:https://www.php.net/releases/8.0/en.php

(B)安全研究者phith0n发布的文章《有安全研究者混入了PHP 8.0开发组!》:https://mp.weixin.qq.com/s/0HSAPYY2PjbwEN3MhI4SkA

(C)《从 PHP 7.4.x 移植到 PHP 8.0.x》:https://www.php.net/manual/zh/migration80.php

二、语法引入和变更

1、不再支持大括号的数组写法(PHP 7.4引入)

以往我们会使用大括号来获取字符串某一个位置的内容:

$a = "abfdcccc";
$b = $a{0};

从PHP 7.4开始,该写法将不被支持,会报E_COMPILE_ERROR

[E_COMPILE_ERROR][Error Code 64] Array and string offset access syntax with curly braces is no longer supported

三、类引入和变更

1、Throwable接口引入(PHP 7.0引入)

从PHP 7.0开始,官方引入Throwable接口。现在Exception类和Error类均是Throwable接口的实现。

如果使用了set_exception_handler接收默认异常处理时,请在PHP 7.0检查是否允许实现了Throwable接口的实例传递。如果只支持传递Exception实例,则在PHP 7.0开始会存在问题,因为有可能会传递新增的Error实例。详见:https://www.php.net/manual/en/function.set-exception-handler.php

2、Error类引入(PHP 7.0引入,PHP 7.x强化PHP 8.0强化)

从PHP 7.0开始,官方引入Error类,即所有PHP内部错误类的基类。参见:https://www.php.net/manual/en/class.error.php

后续的PHP 7.x版本中,部分内置扩展把原来的输出warning迁移到抛出Error类,比如:

(A)ext/BCMath错误行为变更(PHP7.3引入):“BCMath Arbitrary Precision Mathematics: All warnings thrown by BCMath functions are now using PHP’s error handling. Formerly some warnings have directly been written to stderr.”

到了PHP 8.0,官方进一步强化了该类使用范畴:使用PHP函数时,如果出现参数验证错误,现在会抛出Error类而不是输出warning。因此,需要留意如何处理更多的异常。

Consistent type errors for internal functions: Most of the internal functions now throw an Error exception if the validation of the parameters fails.

PHP 7例子:

strlen([]); // Warning: strlen() expects parameter 1 to be string, array given

array_chunk([], -1); // Warning: array_chunk(): Size parameter expected to be greater than 0

PHP 8例子:

strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given

array_chunk([], -1); // ValueError: array_chunk(): Argument #2 ($length) must be greater than 0

四、扩展部分

1、ext/mcrypt扩展不再内置(PHP 7.1废弃,PHP 7.2移除)

从PHP 7.1开始,内置的mcrypt扩展被标记为废弃;PHP 7.2开始,mcrypt扩展被从内置库移除。

建议相关函数改用openssl扩展实现,和其它编程语言对接起来相对更通用。

详细见:

https://www.php.net/manual/en/intro.mcrypt.php

https://www.php.net/manual/en/migration71.deprecated.php

2、ext/xmlrpc扩展不再内置(PHP 8.0移除)

从PHP 8.0开始,内置的xmlrpc扩展被移除。

如有需要,请自行从PECL库下载并编译:https://pecl.php.net/package/xmlrpc

3、ext/sodium引入(PHP 7.2引入)

从PHP 7.2开始,官方引入sodium扩展。该扩展依赖libsodium库。

sodium扩展可以替代mcrypt扩展的功能,也能替代openssl扩展中的部分加解密功能。

但笔者建议,如果涉及和其它系统或编程语言的对接,优先使用openssl扩展。

参考:https://www.php.net/manual/en/book.sodium.php

本页永久链接:https://www.orztip.com/?p=526&article_title=php-8-compatibility