向后不兼容的更改

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)
?>
这意味着方法中的静态变量现在表现得与静态属性相同。

在必需参数之前指定的可选参数

现在,在必需参数之前指定的 可选参数 始终被视为必需参数,即使使用 命名参数 调用时也是如此。从 PHP 8.0.0 开始,但在 PHP 8.1.0 之前,以下代码会在定义时发出弃用通知,但在调用时会成功运行。从 PHP 8.1.0 开始,将抛出 ArgumentCountError 类的错误,就像使用位置参数调用时一样。

<?php
function makeyogurt($container = "bowl", $flavour)
{
return
"Making a $container of $flavour yogurt.\n";
}
try
{
echo
makeyogurt(flavour: "raspberry");
}
catch (
Error $e)
{
echo
get_class($e), ' - ', $e->getMessage(), "\n";
}
?>

以上示例在 PHP 8.0 中的输出

Deprecated: Required parameter $flavour follows optional parameter $container
 in example.php on line 3
Making a bowl of raspberry yogurt.

以上示例在 PHP 8.1 中的输出

Deprecated: Optional parameter $container declared before required parameter
 $flavour is implicitly treated as a required parameter in example.php on line 3
ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed

请注意,可以在必需参数之前使用 null 的默认值来指定 可空类型,但该参数仍然是必需的。

返回类型与内部类的兼容性

现在,大多数非 final 内部方法都要求覆盖方法声明兼容的返回类型,否则在继承验证期间会发出弃用通知。如果由于 PHP 跨版本兼容性问题无法为覆盖方法声明返回类型,则可以添加 ReturnTypeWillChange 属性以消除弃用通知。

新关键字

readonly 现在是关键字。但是,它仍然可以用作函数名。

never 现在是保留字,因此不能用它来命名类、接口或特征,也不能在命名空间中使用它。

资源到对象的迁移

一些 资源 已迁移到 对象。使用 is_resource() 进行返回值检查应替换为检查 false

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

默认的错误处理模式已从“静默”更改为“异常”。有关此更改的更多详细信息以及如何显式设置此属性,请参见 MySQLi 报告模式 页面。要恢复以前的行为,请使用: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::PARAM_LOB 调用 PDOStatement::bindColumn() 现在将始终绑定流结果,只要未启用 PDO::ATTR_STRINGIFY_FETCHES。以前,结果将是流或字符串,具体取决于使用的数据库驱动程序和绑定执行的时间。

MySQL 驱动程序

使用模拟准备语句时,结果集中的整数和浮点数现在将使用本机 PHP 类型而不是 string 返回。这与本机准备语句的行为一致。可以通过启用 PDO::ATTR_STRINGIFY_FETCHES 选项来恢复以前的行为。

SQLite 驱动程序

结果集中的整数和浮点数现在将使用本机 PHP 类型返回。可以通过启用 PDO::ATTR_STRINGIFY_FETCHES 选项来恢复以前的行为。

Phar

为了符合 ArrayAccess 接口,Phar::offsetUnset()PharData::offsetUnset() 不再返回 bool

标准

version_compare() 不再接受未记录的操作符缩写。

htmlspecialchars()htmlentities()htmlspecialchars_decode()html_entity_decode()get_html_translation_table() 现在默认使用 ENT_QUOTES | ENT_SUBSTITUTE,而不是 ENT_COMPAT。这意味着 ' 将转义为 &#039;,而以前什么也没做。此外,格式错误的 UTF-8 将被替换为 Unicode 替换字符,而不是导致空字符串。

debug_zval_dump() 现在会打印带有引用计数的引用包装器的引用计数,而不是仅仅在值前面加上 &。这更准确地模拟了自 PHP 7.0 以来引用的表示方式。

debug_zval_dump() 现在会打印 interned,而不是为内部字符串和不可变数组打印虚拟引用计数。

标准 PHP 库 (SPL)

SplFixedArray 现在将像 array 一样进行 JSON 编码。

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top