尽管本节没有明确说明,但每个新函数、类、interface、枚举或常量都可能导致抛出重复声明 Error。
exit()(和 die())语言结构现在的行为更像函数。这意味着现在可以传递
callable,受 strict_types
声明语句的影响,并且现在执行往常的类型强制,而不是将任何非整数值转换为字符串。
不再允许在 __clone()
里间接修改 readonly 属性,例如 $ref = &$this->readonly
。这在 readonly
初始化中已禁止,并且是“克隆期间 readlony 重新初始化”实现中的一个疏忽。
上传文件和 tempnam() 函数创建的文件名现在为 13 个字节。总长度仍取决于平台。
多个 resource 已迁移到 object。除非另有说明,否则 is_resource()
的返回值检查应替换为 false
检查。
DBA 函数现在接受并返回
Dba\Connection 对象,而不是
dba_connection
resource。
ODBC 函数现在接受并返回
Odbc\Result 对象,而不是
odbc_result
resource。
ODBC 函数现在接受并返回
Odbc\Connection 对象,而不是
odbc_connection
resource。
SoapClient::$httpurl 属性现在是
Soap\Url 对象,而不是
soap_url
resource。
检查使用 is_resource()(即
is_resource($client->httpurl)
)应该替换为检查
是否为 null
(即 $client->httpurl !== null
)。
SoapClient::$sdl 属性现在是
Soap\Sdl 对象,而不是
soap_sdl
resource。
检查使用 is_resource()(即
is_resource($client->sdl)
)应该替换为检查
是否为 null
(即 $client->sdl !== null
)。
添加了因编程错误(即将无效值提供给参数)而触发新的警告和异常。
如果 timeout
参数小于 0
或大于
PHP_INT_MAX
,curl_multi_select()
现在会抛出 ValueError。
当传入无效的 quality
时,imagejpeg(), imagewebp(), imagepng(), imageavif()
现在抛出 ValueError。
当传递无效的 speed
参数值时,imageavif()
现在将抛出 ValueError。
如果 width
或 height
参数溢出,imagescale() 现在将抛出 ValueError。
当传入无效的 mode
参数时,imagescale()
现在将抛出 ValueError。
如果 sub
或 plus
参数溢出,imagefilter() 现在使用 IMG_FILTER_SCATTER
过滤器将抛出 ValueError。
如果 domain
是空字符串,bind_textdomain_codeset(), textdomain(), d()*gettext() 现在 抛出 ValueError。
resourcebundle_get()、ResourceBundle::get() 和在 ResourceBundle 对象上访问偏移量现在会抛出:
如果 locale
无效,则
IntlDateFormatter::__construct() 抛出
ValueError。
如果 locale
无效,则
NumberFormatter::__construct() 抛出
ValueError。
mb_encode_numericentity() 和
mb_decode_numericentity() 现在检测
map
是否仅由 int
构成,如果不是,则抛出 ValueError。
如果 type
无效,mb_http_input()
现在始终抛出 ValueError。
mb_http_output() 现在检测
encoding
是不是不包含 null 字节,如果包含,会抛出
ValueError。
当 row
小于或等于 0
时,odbc_fetch_row() 返回 false
。在这种情况下会发出 warning。
pcntl_sigprocmask()、pcntl_sigwaitinfo() 和 pcntl_sigtimedwait() 函数现在会抛出:
signals
数组为空,则抛出 ValueError(如果
mode
SIG_SETMASK
则
pcntl_sigprocmask() 除外)
signals
数组的值不是 int,则抛出 TypeError
signals
数组不是有效的信号编号,则抛出 ValueError
如果 mode
不是 SIG_BLOCK
、SIG_UNBLOCK
或 SIG_SETMASK
中的一个,pcntl_sigprocmask()
现在将抛出 ValueError。
pcntl_sigtimedwait() 函数现在将抛出:
seconds
小于 0
则抛出 ValueError
nanoseconds
小于 0
或者大于
1e9
,则抛出 ValueError
seconds
和 nanoseconds
是 0
,则抛出 ValueError
使用非 XML 对象调用 simplexml_import_dom() 将抛出 TypeError 而不是 ValueError
round() 函数现在会验证 mode
的值,如果无效,则抛出 ValueError。之前无效模式会解释为 PHP_ROUND_HALF_UP
。
当 separator
和 enclosure
参数值的长度不为一个字节,或者
escape
参数值不为一个字节或者空字符串,str_getcsv() 现在将抛出
ValueError。该行为已与 fputcsv() 和
fgetcsv() 行为相同。
如果 mode
无效,php_uname()
函数现在会抛出 ValueError。
unserialize() 的 "allowed_classes"
选项如果不是类名 array,现在会抛出 TypeError
和 ValueError。
传递无效的字符编码给 XMLReader::open() 或 XMLReader::XML() 现在会引发 ValueError。
传递包含 null 字节的 string,之前会发出 warning,现在会引发 ValueError。
传递包含 null 字节的 string,之前会发出 warning,现在会引发 ValueError。
XSLTProcessor::setParameter() 现在会在参数包含 null 字节时抛出 ValueError。这实际上从一开始就没有正确运行过,这就是它现在抛出异常的原因。
现在,使用非 XML 对象调用 XSLTProcessor::importStyleSheet() 会引发 TypeError 而不是 ValueError。
如果在求值期间调用 PHP 函数回调失败,则现在会抛出而不是发出 warning。
如果无法分配新节点,某些 DOM 方法以前会返回 false
或带有 code DOM_PHP_ERR
的
DOMException。现在,它们会一致地抛出带有 code DOM_INVALID_STATE_ERR
的 DOMException。这种情况极少发生,受影响的可能性也很低。因此,DOMImplementation::createDocument()
现在暂定返回类型为 DOMDocument,而不是 DOMDocument|false
。
以前,可以克隆 DOMXPath 对象,但会导致对象不可用。现在则不可以,克隆 DOMXPath 对象会引发 Error。
已移除 DOMImplementation::getFeature() 方法。
GMP 类现在是 final,并且再也不能继承。
对于无效字符串(包含编码错误),mb_substr() 现在以与大多数其他 mbstring 函数相同的方式解释字符索引。这意味着 mb_strpos() 返回的字符索引可以传递给 mb_substr()。
对于 SJIS-Mac (MacJapanese) 字符串,传递给 mb_substr() 的字符索引现在指向的是将字符串转换为 Unicode 时生成的 Unicode 码点的索引。这很重要,因为大约 40 个 SJIS-Mac 字符在转换为 Unicode 时会变成多个 Unicode 代码点的序列。
已移除未使用和未记录的常量 MYSQLI_SET_CHARSET_DIR
。
已移除 MYSQLI_STMT_ATTR_PREFETCH_ROWS
常量。mysqlnd 无法使用该功能。
已移除 MYSQLI_CURSOR_TYPE_FOR_UPDATE
和 MYSQLI_CURSOR_TYPE_SCROLLABLE
常量。此功能从未实现过,无论是 mysqlnd 还是 libmysql。
已移除未使用的 MYSQLI_TYPE_INTERVAL
常量(当前是 MYSQLI_TYPE_ENUM
的存根(stub)和别名)。
对于 MySQL 服务器 8.0.24 及以上版本,MySQL 服务器等待超时报告的错误 code 已从 2006
更改为 4031
。
64 位架构上 opcache.interned_strings_buffer
设置的最大值现在是 32767
。以前是 4095
。
JIT 的默认配置值分别从 opcache.jit=tracing
和 opcache.jit_buffer_size=0
更改为 opcache.jit=disable
和 opcache.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_sigprocmask()、pcntl_sigwaitinfo() 和
pcntl_sigtimedwait() 函数现在在失败时始终返回 false
。以前在某些情况下,它可能返回值 -1
。
捆绑的 pcre2lib 已更新至版本 10.44。因此,这意味着 {,3}
现在识别为量词而不是文本。此外,UCP
模式下某些字符类的含义已发生改变。请参阅 » PCRE2
变更日志,了解完整的变更日志。
Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER
和 Pdo\Dblib::ATTR_DATETIME_CONVERT
属性现在是 bool 属性,而不是 int 属性。因此,通过 PDO::setAttribute() 设置属性并通过
PDO::getAttribute() 检索属性并返回 bool 值。
PDO::ATTR_AUTOCOMMIT
属性现在是 bool 属性,而不是 int 属性。因此,通过 PDO::setAttribute()
设置属性并通过 PDO::getAttribute() 检索属性并返回 bool 值。
该扩展现在公开了一些 Firebird C++ API,因此编译此扩展现在需要 C++ 编译器。此外,现在必须针对 fbclient 3.0 或更高版本编译该扩展。
PDO::ATTR_AUTOCOMMIT
、PDO::ATTR_EMULATE_PREPARES
和
PDO::MYSQL_ATTR_DIRECT_QUERY
属性现在是 bool 属性,而不是 int 属性。因此,通过
PDO::setAttribute() 设置属性并通过 PDO::getAttribute()
检索属性并返回 bool 值。
DSN 的凭证在设置时优先于 PDO 构造方法中的凭证,更接近文档状态。
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
SoapClient::$typemap 现在是 array,而不是 resource。使用
is_resource() 检查(即 is_resource($client->typemap)
)应替换为对 null
的检查(即 $client->typemap !== null
)。
SOAP 扩展获得了对 session 扩展的可选依赖。如果在编译 PHP 时未使用 session 扩展,并且启用了 --enable-rtld-now 配置 flag,则如果还使用了 SOAP 扩展,则将发生启动错误。要解决此问题,请不要使用 rtld-now 或加载 session 扩展。
当使用 strcspn() 并将 characters
设为空字符串时,现在将返回字符串的长度,而不是错误地停止在第一个 null 字节处。
http_build_query() 现在可以正确处理支持的枚举。
stream_bucket_make_writeable() 和 stream_bucket_new() 现在将返回 StreamBucket 实例而不是 stdClass 实例。
构造方法失败现在会引发 exception,而不是发出 warning 并导致对象损坏。
xml_set_()*_handler() 函数现在声明并检查 handler
参数的 callable|string|null 有效签名。此外,现在检查与使用
xml_set_object() 设置的对象方法名称相对应的 string 类型的值,以查看该方法是否存在于先前传递的对象的类中。这意味着现在必须始终在将方法名称设置为
callable 之前调用 xml_set_object()。传递空字符串来禁用处理程序仍然是允许的,但已弃用。
然而,由于 xml_set_object() 和传递非 callable 的字符串已弃用。建议使用直接引用该方法的 callable 来更改此类实例。