当 opcache.preload_user 是当前系统用户时,现在允许在预加载期间使用 FFI::load()。以前,如果设置了 opcache.preload_user 指令,则预加载期间无法调用 FFI::load()。
如果 socket 路径比操作系统支持的路径长度更长,则 FPM CLI 测试现在会失败。
在 CLI 和 phpdbg SAPI 中,以 root 身份运行时,不再需要设置 opcache.preload_user 指令来进行预加载。在其它 SAPI 中,以 root 身份运行时需要此指令,因为在 SAPI 切换到非特权用户之前进行预加载。
如果在 socket 连接上有任何缓冲数据,而不是等待更多数据,fread() 阻塞会立即返回。
内存流在偏移量超过末尾时不会失败。而是在下次写入时内存会增加,并且旧末尾和偏移量之间的数据会以与文件相同的方式填充零字节。
现在,stat() 访问操作(像 file_exists() 及其类似这样)将使用真实路径而不是实际的 stream 路径。这与 stream 的打开方式保持一致。
STDOUT
、STDERR
和 STDIN
流不再因资源销毁而关闭,这主要是在
CLI 完成时关闭。然而,仍然可以使用 fclose() 和类似函数明确关闭这些流。
gc_status() 添加下列 8 个字段:
"running"
=> bool"protected"
=> bool"full"
=> bool"buffer_size"
=> int"application_time"
=> float:总的应用时间,以秒为单位(包含 collector_time)"collector_time"
=> float:垃圾回收所花费的时间,单位为秒(包括 destructor_time 和 free_time)"destructor_time"
=> float:在垃圾回收期间执行析构方法的时间,单位为秒"free_time"
=> float:在垃圾回收期间花费在释放值上的时间,单位为秒class_alias() 现在支持创建内部类的别名。
在运行时使用 ini_set('open_basedir', ...);
设置 open_basedir 时,不再接受包含父目录(..
)的路径。以前只禁止以
..
开头的路径。这可以通过在路径前加上./
来轻松规避。
用户异常处理程序现在可以在关闭期间捕获异常。
highlight_string() 和 highlight_file() 的 HTML 结果已经改变。外部
HTML 标签之间的空格已移除。换行符和空格不再转换为 HTML 实体。整个 HTML 现在包装在 <pre>
标签中。外部的 <span>
标签已经与 <code>
标签合并。
easter_date() 现在在 64 位系统上支持 1970 到 20 亿年,以前它只支持 1970 到 2037 年。
curl_getinfo() 现在支持两个新常量:CURLINFO_CAPATH
和
CURLINFO_CAINFO
。如果 option 为 null
,则会显示以下两个额外的键:"capath"
和 "cainfo"
。
DOMCharacterData::appendData() 的返回值临时修改为 true。
DOMDocument::loadHTML()、DOMDocument::loadHTMLFile()、DOMDocument::loadXML()
和 DOMDocument::loadXMLFile() 现在有了临时返回类型 bool。之前,返回类型是
DOMDocument|bool
,但是自 PHP 8.0.0 起,DOMDocument 不再是静态可调用,所以不能返回。
imagerotate() 的签名已经更改。已经移除 $ignore_transparent
参数,因为自 PHP 5.5.0 起已忽略。
datefmt_set_timezone()(及其别名 IntlDateformatter::setTimeZone())现在在成功时返回
true
,以前返回 null
。
IntlBreakiterator::setText() 现在在失败时返回 false
,之前返回 null
。现在在成功时返回 true
,以前返回 null
。
IntlChar::enumCharNames() 现在返回 bool。之前成功时返回 null
,失败时返回 false
。
当设置了无效的区域,IntlDateFormatter::__construct() 将抛出 U_ILLEGAL_ARGUMENT_ERROR
。
mb_strtolower() 和 mb_convert_case() 实现了对希腊字母 sigma
的条件转换规则,条件转换只适用于 MB_CASE_LOWER
和 MB_CASE_TITLE
模式,不适用于 MB_CASE_LOWER_SIMPLE
和 MB_CASE_TITLE_SIMPLE
。
mb_decode_mimeheader() 根据 RFC 2047 的要求解释 QPrint 编码的 MIME 编码单词中的下划线,它们将转换为空格。在这样的
MIME 编码单词中,下划线必须被编码为 "=5F"
。
在极少数情况下,mb_encode_mimeheader() 会对输入字符串进行传输编码,在 PHP 8.2 中会将输入字符串作为原始 ASCII 传递。
当输入字符串使用 QPrint 编码时,mb_encode_mimeheader() 不再丢弃 NUL(零)字节。之前会导致某些文本编码的字符串,特别是 UTF-16 和 UTF-32,会被 mb_encode_mimeheader 破坏。
mb_detect_encoding() 现在的的“非严格”模式行为如文档中所述。之前,如果在所有候选编码中输入字符串的相同字节(比如,第一个字节)是无效的,将会返回
false
。一般来说,当看到无效字节时,将会从考虑(consideration)中剔除候选编码,如果相同的输入字节剔除了考虑中的所有剩余编码,将返回
false
。另一方面,如果所有的候选编码一个个都剔除了,它将返回最后剔除的那个,而不考虑字符串中可能遇到的编码错误。这与文档中描述的行为不同,文档中说:“如果 strict
设置为 false,将返回最接近的匹配编码”。
当 $constructor_args
参数不为空且类没有构造方法时,mysqli_fetch_object()
现在抛出 ValueError 而不是 Exception。
当都没有传递 $read
和 $error
参数时,mysqli_poll() 现在会抛出 ValueError。
mysqli_field_seek() 和 mysqli_result::field_seek() 现在返回类型指定为 true 而不是 bool。
odbc_autocommit() 现在接受 $enable
参数为 null
。传递 null
与只传递 1 个参数的行为相同,即表明是否启用自动提交功能。
当 $constructor_args
参数不为空且类没有构造方法时,pg_fetch_object()
现在抛出 ValueError 而不是 Exception。
当指定的表无效时,pg_insert() 现在抛出 ValueError 而不是 E_WARNING
。
当字段的值/类型与 PostgreSQL 的类型不匹配时,pg_insert() 和 pg_convert() 会抛出
ValueError 或 TypeError,而不是 E_WARNING
。
pg_fetch_result()、pg_field_prtlen() 和
pg_field_is_null() 的 $row
参数现在可以为 null。
mt_srand() 和srand() 变更为不使用检查参数的数量的方式来确定是否应该使用随机种子。传递 null
将生成随机种子,0
将使用 0 作为种子。函数现在与 Random\Engine\Mt19937::__construct() 一致。
ReflectionClass::getStaticProperties() 的返回类型不再可为 null。
unserialize() 所触发的 E_NOTICE
被提升为 E_WARNING
。
如果输入包含未使用的字节,unserialize() 现在会抛出新的 E_WARNING
。
array_pad() 现在只接受数组元素可拥有的最大数量限制,以前每次最多只能添加 1048576 个元素。
strtok() 在开始标切分时,如果没有提供 token,则引发 E_WARNING
。
当生成 salt 失败时,password_hash() 现在将底层的 Random\RandomException 链到
ValueError 的 $previous
Exception。
如果使用数组作为 proc_open() 的 $command
,则现在必须至少有一个非空元素。否则会抛出
ValueError。
array_sum() 和 array_product() 现在会在数组中的值不能转换为 int/float 时发出警告。之前会忽略数组和对象,而其他所有值都被强制转换为 int。此外,定义了数字转换的对象(例如 GMP)现在会强制转换,而不是忽略。
现在 number_format() 的 $decimal
可以正确处理负整数。$decimal
为负数时,$num
值会四舍五入到小数点前 $decimals
位,而之前的 $decimals
会忽略负数,并且四舍五入到小数点后 0 位。
在 strrchr() 中增加了新的参数 $before_needle
,它的行为与 strstr() 或
stristr() 函数中的对应参数类似。
对于未包含关闭引号的最后一个字段,str_getcsv() 和 fgetcsv() 现在返回空字符串,而不是带单个 null 字节的字符串。
在类型 bool 的值上使用
自增/减运算符(++
/--
)将会抛出警告。这是因为虽然目前没有效果,但是将来行为将是
$bool += 1
。
在类型 null 的值上使用
自减运算符(--
)将会抛出警告。这是因为虽然目前没有效果,但是将来行为将是
$null -= 1
。
内部对象实现 _IS_NUMBER 转换,但不是重写加减法的 do_operator 处理程序,现在可以像 $o += 1
或 $o -= 1
一样递增和递减。
DOM 的生命周期机制已经被重写,这样默默删除的节点仍然可以获取,之前这样做会导致异常。
已弃用 assert.*
INI 设置。这包括以下 INI 设置:
zend.max_allowed_stack_size 是新的 INI
指令,用于设置允许的最大栈大小。可能的值是
0
(检测进程或线程的最大栈大小)、-1(无限制)或正数的单位为字节的值。默认值为
0
。当无法检测到进程或线程的最大的栈大小时,使用已知的系统默认值。设置的值过高效果等同于不限制栈的大小。Fiber
使用 fiber.stack_size 作为允许的最大栈大小。当进程调用栈超过
zend.max_allowed_stack_size-zend.reserved_stack_size 个字节时,将抛出
Error,以防止栈溢出引发分段错误,目的是使调试更容易。在没有控制递归调用内部函数或者魔术方法 __toString()、__clone()、__sleep()、__destruct()
期间,栈的大小会增加。这与栈缓冲区溢出无关,也不是安全特性。
zend.reserved_stack_size 是新的 INI 指令,用于设置预留的栈大小(以字节为单位)。当检查栈大小时,会从最大允许的栈大小中减去,作为缓冲区。
现在遍历 DOMNodeList 时使用了缓存,因此默认情况下请求元素不再需要花费两次的时间。
从节点获取文本内容现在避免了分配,从而提高了性能。
DOMChildNode::remove() 现在运行性能是 O(1)。
file() flags 错误检查现在快了大约 7%。
RecursiveDirectoryIterator 现在循环目录时执行更少的 I/O。