PHP Conference Japan 2024

向后不兼容的更改

虽然在本节中没有明确说明,但每个新的 函数类、接口、枚举常量 可能会导致重新声明 Error 异常被抛出。

PHP 核心

exit() 行为更改

exit()(和 die())语言结构现在表现得更像一个函数。这意味着它们现在可以像 callable 一样传递,受 strict_types declare 语句的影响,并且现在执行通常的类型强制转换,而不是将任何非整数值强制转换为字符串。

因此,将无效类型传递给 exit()die() 现在始终会导致抛出 TypeError 异常。

比较期间的递归

在比较期间遇到递归现在会导致抛出 Error 异常,而不是 E_ERROR 致命错误。

只读属性的间接修改

不再允许在 __clone() 中间接修改只读属性,例如 $ref = &$this->readonly。这在只读初始化中就已经禁止了,并且是“克隆期间只读重新初始化”实现中的一个疏忽。

常量类型的更改

PHP_DEBUGPHP_ZTS 常量现在为 bool 类型。以前它们是 int 类型。

临时文件名长度

上传的文件和 tempnam() 函数创建的文件的名称现在长了 13 个字节。总长度仍然取决于平台。

删除 E_STRICT 错误级别

E_STRICT 错误级别已被删除,因为它在 PHP 引擎中不再使用。E_STRICT 常量已被弃用。

现在已类型化的扩展类常量

以下扩展类常量现在在其常量上声明一个类型

资源到对象的迁移

一些 资源 已迁移到 对象。使用 is_resource() 检查返回值应替换为检查 false,除非另有说明。

DBA

DBA 函数现在接受并返回 Dba\Connection 对象,而不是 dba_connection 资源

ODBC

ODBC 函数现在接受并返回 Odbc\Result 对象,而不是 odbc_result 资源

ODBC 函数现在接受并返回 Odbc\Connection 对象,而不是 odbc_connection 资源

SOAP

SoapClient::$httpurl 属性现在是一个 Soap\Url 对象,而不是 soap_url 资源。使用 is_resource()(即 is_resource($client->httpurl))进行的检查应替换为检查 null(即 $client->httpurl !== null)。

SoapClient::$sdl 属性现在是一个 Soap\Sdl 对象,而不是 soap_sdl 资源。使用 is_resource()(即 is_resource($client->sdl))进行的检查应替换为检查 null(即 $client->sdl !== null)。

新的警告和异常

添加了新的警告和异常,这些警告和异常会在编程错误(即作为参数提供的无效值)时触发。

Curl

如果 timeout 参数小于 0 或大于 PHP_INT_MAX,则 curl_multi_select() 现在会抛出 ValueError

Gd

imagejpeg()imagewebp()imagepng()imageavif() 在传递无效 quality 时现在会抛出 ValueError

如果传递了无效的 speed 参数值,则 imageavif() 现在会抛出 ValueError

如果 widthheight 参数下溢/溢出,则 imagescale() 现在会抛出 ValueError

如果传递了无效的 mode 参数值,则 imagescale() 现在会抛出 ValueError

如果 subplus 参数下溢/溢出,则 imagefilter() 使用 IMG_FILTER_SCATTER 过滤器时现在会抛出 ValueError

Gettext

bind_textdomain_codeset()textdomain()d()*gettext() 如果 domain 为空字符串,则现在会抛出 ValueError

Intl

resourcebundle_get()ResourceBundle::get() 和访问 ResourceBundle 对象上的偏移量现在会抛出

如果 locale 无效,则 IntlDateFormatter::__construct() 会抛出 ValueError

如果 locale 无效,则 NumberFormatter::__construct() 会抛出 ValueError

MBString

mb_encode_numericentity()mb_decode_numericentity() 现在会检查 map 是否仅由 int 组成,如果不是,则会抛出 ValueError

mb_http_input() 现在如果 type 无效,则始终会抛出 ValueError

mb_http_output() 现在会检查 encoding 是否包含空字节,如果包含,则会抛出 ValueError

ODBC

odbc_fetch_row()row 小于或等于 0 时,返回 false。在这种情况下,现在会发出警告。

PCNTL

pcntl_sigprocmask()pcntl_sigwaitinfo()pcntl_sigtimedwait() 函数现在会抛出

pcntl_sigprocmask() 函数现在如果 mode 不是 SIG_BLOCKSIG_UNBLOCKSIG_SETMASK 之一,则会抛出 ValueError

pcntl_sigtimedwait() 函数现在会抛出

  • 如果 seconds 小于 0,则会抛出 ValueError
  • 如果 nanoseconds 小于 0 或大于 1e9,则会抛出 ValueError
  • 如果 secondsnanoseconds 都为 0,则会抛出 ValueError

SimpleXML

使用非 XML 对象调用 simplexml_import_dom() 现在会抛出 TypeError 而不是 ValueError

标准

round() 函数现在会验证 mode 的值,对于无效的模式,会抛出 ValueError。以前,无效的模式会被解释为 PHP_ROUND_HALF_UP

str_getcsv() 现在如果 separatorenclosure 参数的长度不为 1 字节,或者 escape 参数的长度不为 1 字节且不为空字符串,则会抛出 ValueError。这使得其行为与 fputcsv()fgetcsv() 完全一致。

php_uname() 函数现在如果 mode 无效,则会抛出 ValueError

unserialize()"allowed_classes" 选项现在如果它不是类名称的 array,则会抛出 TypeErrorValueError

XMLReader

XMLReader::open()XMLReader::XML() 传递无效的字符编码现在会抛出 ValueError

传递包含空字节的 string 以前会发出警告,现在会抛出 ValueError

XMLWriter

传递包含空字节的 string 以前会发出警告,现在会抛出 ValueError

XSL

XSLTProcessor::setParameter() 现在如果其参数包含空字节,则会抛出 ValueError。这在以前实际上从未正常工作过,这就是它现在抛出异常的原因。

使用非 XML 对象调用 XSLTProcessor::importStyleSheet() 现在会抛出 TypeError 而不是 ValueError

在评估期间未能调用 PHP 函数回调现在会抛出异常而不是发出警告。

DOM

一些 DOM 方法以前如果无法分配新的节点,则会返回 false 或代码为 DOM_PHP_ERRDOMException。现在它们始终抛出代码为 DOM_INVALID_STATE_ERRDOMException。这种情况极不可能发生,受影响的概率很低。因此,DOMImplementation::createDocument() 现在具有 DOMDocument 的暂定返回类型,而不是 DOMDocument|false

以前,可以克隆 DOMXPath 对象,但这会导致生成一个不可用的对象。这现在不再可能,克隆 DOMXPath 对象现在会抛出 Error

DOMImplementation::getFeature() 方法已被移除。

GMP

GMP 类现在是 final 的,不能再扩展了。

MBString

对于无效字符串(包含编码错误的字符串),mb_substr() 现在以与大多数其他 mbstring 函数相同的方式解释字符索引。这意味着由 mb_strpos() 返回的字符索引可以传递给 mb_substr()

对于 SJIS-Mac (MacJapanese) 字符串,传递给 mb_substr() 的字符索引现在指的是将字符串转换为 Unicode 时生成的 Unicode 代码点的索引。这很重要,因为大约 40 个 SJIS-Mac 字符会转换为多个 Unicode 代码点的序列。

MySQLi

未使用的且未记录的常量 MYSQLI_SET_CHARSET_DIR 已被移除。

MYSQLI_STMT_ATTR_PREFETCH_ROWS 常量已被移除。mysqlnd 不支持此功能。

MYSQLI_CURSOR_TYPE_FOR_UPDATEMYSQLI_CURSOR_TYPE_SCROLLABLE 常量已被移除。此功能从未实现过,无论是 mysqlnd 还是 libmysql。

未使用的 MYSQLI_TYPE_INTERVAL 常量已被移除,它目前是一个存根,也是 MYSQLI_TYPE_ENUM 的别名。

MySQLnd

MySQL 服务器等待超时报告的错误代码已从 2006 更改为 4031(对于 MySQL 服务器版本 8.0.24 及更高版本)。

Opcache

64 位架构上 opcache.interned_strings_buffer 设置的最大值现在为 32767。以前是 4095

JIT

JIT 的默认配置值已从 opcache.jit=tracingopcache.jit_buffer_size=0 分别更改为 opcache.jit=disableopcache.jit_buffer_size=64M

这不会影响默认的可观察行为,因为 JIT 仍然默认禁用。但是,它现在通过 opcache.jit 设置禁用,而不是 opcache.jit_buffer_size。这可能会影响以前仅通过 opcache.jit_buffer_size 启用 JIT 的用户,而没有使用 opcache.jit 指定 JIT 模式。要启用 JIT 编译,请相应地设置 opcache.jit 配置值。

如果启用了 JIT 编译,则如果 JIT 编译器的初始化由于任何原因失败,PHP 现在将在启动时以致命错误退出。

PCNTL

pcntl_sigprocmask()pcntl_sigwaitinfo()pcntl_sigtimedwait() 函数现在在失败时始终返回 false。在某些情况下,以前它可能会返回 -1

PCRE

捆绑的 pcre2lib 已更新至 10.44 版本。因此,这意味着 {,3} 现在被识别为量词而不是文本。此外,UCP 模式下某些字符类的含义已更改。请参阅 » PCRE2 Changelog 以获取完整的变更日志。

PDO_DBLIB

Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIERPdo\Dblib::ATTR_DATETIME_CONVERT 属性现在充当布尔属性而不是整数属性。因此,通过 PDO::setAttribute() 设置属性并通过 PDO::getAttribute() 检索属性时,预期或返回 bool

PDO_FIREBIRD

PDO::ATTR_AUTOCOMMIT 属性现在充当布尔属性而不是整数属性。因此,通过 PDO::setAttribute() 设置属性并通过 PDO::getAttribute() 检索属性时,预期或返回 bool

扩展现在公开了一些 Firebird C++ API,因此构建此扩展现在需要 C++ 编译器。此外,扩展现在必须针对 fbclient 3.0 或更高版本进行编译。

PDO_MYSQL

PDO::ATTR_AUTOCOMMITPDO::ATTR_EMULATE_PREPARESPDO::MYSQL_ATTR_DIRECT_QUERY 属性现在充当布尔属性而不是整数属性。因此,通过 PDO::setAttribute() 设置属性并通过 PDO::getAttribute() 检索属性,期望或返回一个 bool

PDO_PGSQL

DSN 的凭据(如果设置)优先于其 PDO 构造函数对应项,更接近文档说明。

SimpleXML

SimpleXMLElement 不仅仅是 XML 元素的表示,它还是一个 RecursiveIterator。在 PHP 8.4.0 之前,它的一些方法(例如 SimpleXMLElement::asXML()SimpleXMLElement::getName())以及将此类实例转换为 string 会隐式重置迭代器。

这可能导致意外的无限循环,因为迭代器被倒带。例如

<?php

$xmlString
= "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);

$nodes = $xml->a->b;
foreach (
$nodes as $nodeData) {
echo
"nodeData: " . $nodeData . "\n";

$xml = $nodes->asXml();
}

将导致无限循环。

nodeData: 1
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
// ...

但是,此行为现已得到纠正,并且 SimpleXMLElement 将不再隐式重置迭代器数据,除非显式倒带。这意味着前面的示例现在将产生

nodeData: 1
nodeData: 2
nodeData: 3

SOAP

SoapClient::$typemap 现在是 array 而不是 resource。使用 is_resource()(即 is_resource($client->typemap))进行的检查应替换为检查 null(即 $client->typemap !== null)。

SOAP 扩展获得了对 session 扩展的可选依赖项。如果 PHP 在没有 session 扩展的情况下构建并且启用了 --enable-rtld-now 配置标志,则如果也使用了 SOAP 扩展,现在将发生启动错误。要解决此问题,请勿使用 rtld-now 或加载 session 扩展。

标准

当使用 strcspn()characters 为空字符串时,现在将返回字符串的长度,而不是错误地停止在第一个空字节处。

http_build_query() 现在可以正确处理后备枚举。

stream_bucket_make_writeable()stream_bucket_new() 现在将返回一个 StreamBucket 实例,而不是 stdClass 的实例。

Tidy

构造函数中的错误现在会抛出异常,而不是发出警告并导致对象损坏。

XML

xml_set_()*_handler() 函数现在声明并检查 handler 参数的有效签名为 callable|string|null。此外,对应于对象方法名称的 string 类型的值(使用 xml_set_object() 设置的对象)现在将被检查以查看该方法是否存在于先前传递的对象的类中。这意味着 xml_set_object() 现在必须始终在将方法名称设置为 callable 之前调用。传递空字符串以禁用处理程序仍然允许,但已弃用。

但是,由于 xml_set_object() 和传递非 callable 字符串已弃用。建议使用直接引用方法的 callable 更改此类实例。

添加注释

用户贡献的注释

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