不向后兼容的变更

PHP 核心中不向后兼容的变更

以数组形式访问非数组

尝试以数组方式访问 nullboolintfloatresource (例如 $null["key"])将会抛出 notice 通知。

get_declared_classes() 函数

get_declared_classes() 函数将不再返回匿名的类,假如它们没有被实例化的话。

fn 关键词

fn 成为了保留关键词。需要特别注意,它不能再做为函数名或类名使用,但是仍然可以做为方法名和常量名存在。

文件尾部的 <?php 标签

文件尾部的 <?php 标签(不包含空行)将会被解释成一个 PHP 头标签。Previously it was interpreted either as a short opening tag followed by literal php and resulted in a syntax error (with short_open_tag=1) or was interpreted as a literal <?php string (with short_open_tag=0).

Stream wrappers

When using include/require on a stream, streamWrapper::stream_set_option() will be invoked with the STREAM_OPTION_READ_BUFFER option. Custom stream wrapper implementations may need to implement the streamWrapper::stream_set_option() method to avoid a warning (always returning false is a sufficient implementation).

Serialization 序列化

序列化类型 o 被移除。因为它不是由 PHP 生成的,这可能会影响到之前项目中手动生成的序列化字符串。

密码算法常量

密码哈希算法标识符现在是可空字符串,而不再是整数。

  • PASSWORD_DEFAULT 之前是 int 1; 现在是“2y”(在 PHP 7.4.0、7.4.1、7.4.2 中是 null
  • PASSWORD_BCRYPT 之前是 int 1; 现在是 string '2y'
  • PASSWORD_ARGON2I 之前是 int 2; 现在是 string 'argon2i'
  • PASSWORD_ARGON2ID 之前是 int 3; 现在是 string 'argon2id'

应用中如果正常使用了常量 PASSWORD_DEFAULT,PASSWORD_BCRYPT,PASSWORD_ARGON2I 和 PASSWORD_ARGON2ID 将不会受到影响。

htmlentities() 函数

htmlentities() will now raise a notice (instead of a strict standards warning) if it is used with an encoding for which only basic entity substitution is supported, in which case it is equivalent to htmlspecialchars().

fread() and fwrite() 函数

fread()fwrite() 在操作失败的时候会返回 false。之前的版本中会返回空字符串或 0。EAGAIN/EWOULDBLOCK 不视为故障。

这些函数现在也会在失败时发出 NOTICE 通知,例如当试图写入一个只读文件资源时。

BCMath 任意精度数学

如果传递了例如 "32foo" 这种格式不正确的数字,BCMath 函数现在将发出警告。和以前一样,参数将解释为 0。

CURL

现在尝试序列化 CURLFile 类将会生成异常。之前仅会在反序列化时引发。

弃用 CURLPIPE_HTTP1,并在 cURL 7.62.0 起不再支持。

弃用 curl_version()$version 参数。如果传递了任何不等于默认 CURLVERSION_NOW 的值,则会引发警告并忽略参数。

日期和时间

Calling var_dump() or similar on a DateTime or DateTimeImmutable instance will no longer leave behind accessible properties on the object.

DateInterval 对象的比较(使用 ==< 等)现在将生成警告并始终返回 false。之前所有的 DateInterval 对象都认为相等,除非它们有属性。

Intl

The default parameter value of idn_to_ascii() and idn_to_utf8() is now INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.

MySQLi

The embedded server functionality has been removed. It was broken since at least PHP 7.0.

The undocumented mysqli::$stat property has been removed in favor of mysqli::stat().

OpenSSL

The openssl_random_pseudo_bytes() function will now throw an exception in error situations, similar to random_bytes(). In particular, an Error is thrown if the number of requested bytes is less than or equal to zero, and an Exception is thrown if sufficient randomness cannot be gathered. The $crypto_strong output argument is guaranteed to always be true if the function does not throw, so explicitly checking it is not necessary.

Regular Expressions (Perl-Compatible)

When PREG_UNMATCHED_AS_NULL mode is used, trailing unmatched capturing groups will now also be set to null (or [null, -1] if offset capture is enabled). This means that the size of the $matches will always be the same.

PHP Data Objects

Attempting to serialize a PDO or PDOStatement instance will now generate an Exception rather than a PDOException, consistent with other internal classes which do not support serialization.

反射

现在如果尝试对 Reflection 对象序列化将会生成异常。从未支持反射对象序列化并会引起反射对象错误。现在已明确禁止。

ReflectionClassConstantReflectionMethodReflectionProperty 类常量的值发生了变化。

PHP 标准库(SPL)

现在对 ArrayObject 实例调用 get_object_vars() 将始终返回 ArrayObject 本身(或子类)的属性。 Previously it returned the values of the wrapped array/object unless the ArrayObject::STD_PROP_LIST flag was specified.

其它受到影响的操作有:

(array) casts are not affected. They will continue to return either the wrapped array, or the ArrayObject properties, depending on whether the ArrayObject::STD_PROP_LIST flag is used.

SplPriorityQueue::setExtractFlags() will throw an exception if zero is passed. Previously this would generate a recoverable fatal error on the next extraction operation.

ArrayObject, ArrayIterator, SplDoublyLinkedList and SplObjectStorage now support the __serialize() and __unserialize() mechanism in addition to the Serializable interface. This means that serialization payloads created on older PHP versions can still be unserialized, but new payloads created by PHP 7.4 will not be understood by older versions.

Tokenizer

token_get_all() will now emit a T_BAD_CHARACTER token for unexpected characters instead of leaving behind holes in the token stream.

接收到的 Cookies

从 PHP 7.4.11 开始,为了安全考虑,接受到的 Cookie 中的 names 参数不再被 URL 编码。

add a note add a note

User Contributed Notes 1 note

up
8
happydog at kennel17
1 year ago
Re: "The o serialization format has been removed. As it is never produced by PHP, this may only break unserialization of manually crafted strings."

This little-o serialisation format was used by PHP3 but was never generated by PH PHP4 or above.  The deserialization code still recognised it, though, for reasons of backwards-compatibility with PHP3.

However, based on a bit of investigation, it looks like this code has been broken for about 15 years, so although this is listed as a deprecation, in practice it wasn't.

See this Stack Overflow question for a really great answer, with a lot more detail about this: https://stackoverflow.com/questions/65289729/what-was-phps-o-serialization-format-for
To Top