不向后兼容的变更
PHP 内核
$GLOBALS 访问限制
现在访问 $GLOBALS 数组受到一些限制。
对单个数组元素的读写访问 $GLOBALS['var']
与之前一样。
也将继续支持对整个数组 $GLOBALS 的只读访问。
但是,不再支持对整个 $GLOBALS 数组的写访问。
例如,array_pop($GLOBALS)
将返回错误。
在继承的方法中 static 变量的用法
当一个方法使用继承的(而不是重写的)静态变量时,继承的方法将与父级共享这个静态变量。
<?php
class A {
public static function counter() {
static $counter = 0;
$counter++;
return $counter;
}
}
class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3),之前是 int(1)
var_dump(B::counter()); // int(4),之前是 int(2)
?>
返回类型与内部类的兼容性
大多数非 Final 的内部方法现在要求重写方法声明一个可兼容的返回类型,否则在继承时会给出方法废弃的提示。
如果由于 PHP 跨版本兼容性的问题,导致不能为重写方法声明返回类型,则可以添加 #[ReturnTypeWillChange]
注解来取消废弃提示。
新的关键词
现在 readonly
是一个关键词。不过,它仍然可以被用作函数名。
Resource 类型迁移为 Object 类型
一些 资源(resource) 类型已被迁移到 object 类型。
要检查返回值,应该从 is_resource() 检查是否为资源,更改为检查返回值是否等于 false
。
-
现在 FileInfo 函数接收并返回 finfo 对象类型, 而不是
fileinfo
资源(resource) 类型。 -
现在 FTP 函数接收并返回 FTP\Connection 对象类型, 而不是
ftp
资源(resource) 类型。 -
现在 IMAP 函数接收并返回 IMAP\Connection 对象类型, 而不是
imap
资源(resource) 类型。 -
现在 LDAP 函数接收并返回 LDAP\Connection 对象类型, 而不是
ldap link
资源(resource) 类型。 -
现在 LDAP 函数接收并返回 LDAP\Result 对象类型, 而不是
ldap result
资源(resource) 类型。 -
现在 LDAP 函数接收并返回 LDAP\ResultEntry 对象类型, 而不是
ldap result entry
资源(resource) 类型。 -
现在 PgSQL 函数接收并返回 PgSql\Connection 对象类型, 而不是
pgsql link
资源(resource) 类型。 -
现在 PgSQL 函数接收并返回 PgSql\Result 对象类型, 而不是
pgsql result
资源(resource) 类型。 -
现在 PgSQL 函数接收并返回 PgSql\Lob 对象类型, 而不是
pgsql large object
资源(resource) 类型。 -
现在 PSpell 函数接收并返回 PSpell\Dictionary 对象类型, 而不是
pspell
资源(resource) 类型。 -
现在 PSpell 函数接收并返回 PSpell\Config 对象类型, 而不是
pspell config
资源(resource) 类型。
MySQLi
现在 mysqli_fetch_fields() 和
mysqli_fetch_field_direct() 对于 max_length 将返回 0
值。
这一信息可以迭代结果集来计算,并获取最大长度。这是之前 PHP 内部的做法。
常量 MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
不再生效。
常量 MYSQLI_STORE_RESULT_COPY_DATA
不再生效。
传递给 mysqli::store_result() 的 mode
参数的所有值不再生效。
现在 mysqli::connect() 成功时返回 true
而不再返回 null
。
默认错误处理模式已经由 silent 变成了 exceptions,更多详情及如何设置该属性请参见 MySQLi reporting mode 。
要恢复之前的行为习惯,请使用:
mysqli_report(MYSQLI_REPORT_OFF);
现在,扩展 mysqli_stmt::execute() 类需要指定额外的可选参数。
MySQLnd
mysqlnd.fetch_data_copy INI 指令已被取消。 这不会造成用户可见的变化。
OpenSSL
现在 EC 私钥将以 PKCS#8 格式导出,而非像其他秘钥那样的传统格式。
现在 openssl_pkcs7_encrypt() 和 openssl_cms_encrypt() 将默认使用 AES-128-CBC,而非 RC2-40。 RC2-40 加密被认为是不安全的,OpenSSL 3 默认不启用。
PHP 数据对象
现在 PDO::ATTR_STRINGIFY_FETCHES
的类型从 bool 变成了字符串 "0"
或
"1"
。之前的 bool 类型没有被字符串化。
现在当 PDO::ATTR_STRINGIFY_FETCHES
被禁用时,
以 PDO::PARAM_LOB
为参数调用 PDOStatement::bindColumn() 结果将总是绑定一个流。
以前,结果要么是一个流,要么是一个字符串,这取决于所用的数据库驱动及其执行的时间。
MySQL 驱动
现在,当使用模拟预处理时,结果集中的整数及浮点数将会以 PHP 原始类型返回,而不是以 string 类型返回。
这与原生的预处理方式一样。
之前的行为方式可以通过 PDO::ATTR_STRINGIFY_FETCHES
恢复。
SQLite 驱动
现在,结果集中的整数及浮点数将会以 PHP 原始类型返回。
之前的行为方式可以通过 PDO::ATTR_STRINGIFY_FETCHES
恢复。
Phar
为了遵守 ArrayAccess 接口, Phar::offsetUnset() 和 PharData::offsetUnset() 不再以 bool 类型返回。
Standard
version_compare() 函数不再接收未经记录的操作符缩写。
现在 htmlspecialchars()、
htmlentities()、
htmlspecialchars_decode()、
html_entity_decode()、
get_html_translation_table()
使用 ENT_QUOTES | ENT_SUBSTITUTE
作为默认值,而不再是 ENT_COMPAT
。
这意味着 '
被转义为 '
而不像之前那样不作处理。
此外,有缺陷的 UTF-8 将被 Unicode 替代字符(substitute character)替换,而不是产生一个空字符串。
现在 debug_zval_dump() 函数可以打印封装的引用计数了,不仅仅只是打印 &
引用计数的值。
这更准确地模拟了自 PHP 7.0 以来的引用注解。
现在 debug_zval_dump() 可打印 interned
字符串,而不是 interned 字符串和不可变数组的虚拟的引用计数。
PHP 标准库(SPL)
SplFixedArray 将会像 array 类型一样被 JSON 编码。

User Contributed Notes
备份地址:http://www.lvesu.com/blog/php/migration81.incompatible.php