PHP Conference Japan 2024

向后不兼容的更改

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), previously int(1)
var_dump(B::counter()); // int(4), previously 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 的默认值来指定 可空类型,但该参数仍将是必需的。

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

现在,大多数非最终的内部方法都要求覆盖方法声明兼容的返回类型,否则在继承验证期间会发出弃用通知。如果由于 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