向后不兼容的变更

传递函数参数过少时抛出异常

以前,调用用户定义函数时参数过少会发出警告。现在,此警告已提升为 Error 异常。此更改仅适用于用户定义函数,不适用于内部函数。例如

<?php
function test($param){}
test();

以上示例将输出类似于

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

禁止对范围自省函数进行动态调用

禁止对某些函数进行动态调用(以 $func()array_map('extract', ...) 等形式)。这些函数要么检查或修改另一个作用域,要么表现出模棱两可且不可靠的行为。这些函数如下

<?php
(function () {
$func = 'func_num_args';
$func();
})();

以上示例将输出

Warning: Cannot call func_num_args() dynamically in %s on line %d

无效的类、接口和特征名称

以下名称不能用于命名类、接口或特征

数值字符串转换现在支持科学计数法

数值字符串上的整数运算和转换现在支持科学计数法。这也包括 (int) 转换运算,以及以下函数:intval()(其中基数为 10)、settype()decbin()decoct()dechex()

mt_rand() 算法的修复

mt_rand() 现在将默认使用 Mersenne Twister 算法的修复版本。如果依赖于 mt_rand() 的确定性输出,则可以使用 MT_RAND_PHP 作为 mt_srand() 的可选第二个参数来保留旧的(不正确)实现。

rand() 被别名指向 mt_rand(),而 srand() 被别名指向 mt_srand()

rand()srand() 现在已成为 mt_rand()mt_srand() 的别名。这意味着以下函数的输出已更改:rand()shuffle()str_shuffle()array_rand()

禁止在标识符中使用 ASCII 删除控制字符

ASCII 删除控制字符 (0x7F) 不能再用于未引用的标识符中。

error_logsyslog 值的变化而变化

如果 error_log ini 设置设置为 syslog,则 PHP 错误级别将映射到 syslog 错误级别。这与以前的方法相比,在错误日志中带来了更细微的差异,以前所有错误都仅以 notice 级别记录。

不要对不完整的对象调用析构函数

现在,永远不会对在执行构造函数期间抛出异常的对象调用析构函数。在以前的版本中,此行为取决于对象是否在构造函数之外被引用(例如,通过异常回溯)。

call_user_func() 对引用参数的处理

call_user_func() 现在将在调用需要引用作为参数的函数时始终生成警告。以前,这取决于调用是否完全限定。

此外,call_user_func()call_user_func_array() 现在将不再在这种情况下中止函数调用。将发出“预期引用”警告,但调用将照常进行。

空索引运算符不再支持字符串

对字符串应用空索引运算符(例如 $str[] = $x)会抛出致命错误,而不是静默转换为数组。

通过字符串索引访问对空字符串的赋值

通过字符对空字符串进行字符串修改现在与非空字符串类似,即写入超出范围的偏移量会在字符串中填充空格,其中非整型类型将转换为整型,并且仅使用分配字符串的第一个字符。以前,空字符串被静默地视为空数组。

<?php
$a
= '';
$a[10] = 'foo';
var_dump($a);
?>

PHP 7.0 中上述示例的输出

array(1) {
  [10]=>
  string(3) "foo"
}

PHP 7.1 中上述示例的输出

string(11) "          f"

已删除的 ini 指令

已删除以下 ini 指令

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

通过引用赋值时自动创建元素的数组排序已更改

当通过引用赋值自动创建这些元素时,数组中元素的顺序已更改。例如

<?php
$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

PHP 7.0 中上述示例的输出

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

PHP 7.1 中上述示例的输出

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

相等元素的排序顺序

内部排序算法已改进,这可能会导致与以前相比,比较结果相等的元素的排序顺序不同。

注意:

不要依赖于比较结果相等的元素的顺序;它可能会随时更改。

E_RECOVERABLE 错误的错误消息

E_RECOVERABLE 错误的错误消息已从“可捕获的致命错误”更改为“可恢复的致命错误”。

unserialize() 的 $options 参数

unserialize() 的 $options 参数的 allowed_classes 元素现在是严格类型的,即如果给出的不是 arraybool,unserialize() 将返回 false 并发出 E_WARNING

DateTime 构造函数包含微秒

DateTimeDateTimeImmutable 现在在从当前时间(显式或使用相对字符串(例如 "first day of next month"))构造时会正确包含微秒。这意味着对两个新创建的实例的简单比较现在更有可能返回 false 而不是 true

<?php
new DateTime() == new DateTime();
?>

致命错误到 Error 异常的转换

在 Date 扩展中,DateTimeDatePeriod 类无效的序列化数据,或从序列化数据中初始化时区失败,现在将从 __wakeup()__set_state() 方法抛出 Error 异常,而不是导致致命错误。

在 DBA 扩展中,数据修改函数(如 dba_insert())现在将抛出 Error 异常,而不是在键不包含两个元素时触发可捕获的致命错误。

在 DOM 扩展中,无效的模式或 RelaxNG 验证上下文现在将抛出 Error 异常,而不是导致致命错误。类似地,尝试注册不扩展适当基类的节点类,或尝试读取无效的属性或写入只读属性,现在也将抛出 Error 异常。

在 IMAP 扩展中,超过 16385 字节的电子邮件地址将抛出 Error 异常,而不是导致致命错误。

在 Intl 扩展中,在调用父方法之前未在扩展 Collator 的类中调用父构造函数,现在将抛出 Error,而不是导致可恢复的致命错误。此外,克隆 Transliterator 对象现在将在内部转换器克隆失败时抛出 Error 异常,而不是导致致命错误。

在 LDAP 扩展中,为 ldap_batch_modify() 提供未知的修改类型,现在将抛出 Error 异常,而不是导致致命错误。

在 mbstring 扩展中,如果提供了无效的 PHP 表达式并且使用了 'e' 选项,mb_ereg()mb_eregi() 函数现在将抛出 ParseError 异常。

在 Mcrypt 扩展中,如果无法初始化 mcrypt,mcrypt_encrypt()mcrypt_decrypt() 现在将抛出 Error 异常,而不是导致致命错误。

在 mysqli 扩展中,尝试读取无效的属性或写入只读属性,现在将抛出 Error 异常,而不是导致致命错误。

在 Reflection 扩展中,无法检索反射对象或检索对象属性,现在将抛出 Error 异常,而不是导致致命错误。

在 Session 扩展中,不返回字符串作为会话 ID 的自定义会话处理程序,现在将在调用必须生成会话 ID 的函数时抛出 Error 异常,而不是导致致命错误。

在 SimpleXML 扩展中,创建无名或重复属性现在将抛出 Error 异常,而不是导致致命错误。

在 SPL 扩展中,尝试克隆 SplDirectory 对象现在将抛出 Error 异常,而不是导致致命错误。类似地,在迭代对象时调用 ArrayIterator::append() 现在也将抛出 Error 异常。

在标准扩展中,当提供字符串参数作为其第一个参数时,assert() 函数现在将在 PHP 代码无效时抛出 ParseError 异常,而不是导致可捕获的致命错误。类似地,在类范围之外调用 forward_static_call() 现在将抛出 Error 异常。

在 Tidy 扩展中,手动创建 tidyNode 现在将抛出 Error 异常,而不是导致致命错误。

在 WDDX 扩展中,序列化时的循环引用现在将抛出 Error 异常,而不是导致致命错误。

在 XML-RPC 扩展中,序列化时的循环引用现在将抛出 Error 异常实例,而不是导致致命错误。

在 Zip 扩展中,如果 glob 支持不可用,ZipArchive::addGlob() 方法现在将抛出 Error 异常,而不是导致致命错误。

词法绑定的变量不能重用名称

通过 use 结构绑定到 闭包 的变量不能使用与任何 超全局变量$this 或任何参数相同的名称。例如,所有这些函数定义都将导致致命错误

<?php
$f
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

long2ip() 参数类型更改

long2ip() 现在期望 int 而不是 string

JSON 编码和解码

serialize_precision ini 设置现在控制在编码 float 时序列化精度。

解码空键现在将导致空属性名,而不是 _empty_ 作为属性名。

<?php
var_dump
(json_decode(json_encode(['' => 1])));

以上示例将输出类似于

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

当向 json_encode() 提供 JSON_UNESCAPED_UNICODE 标志时,现在将对序列 U+2028 和 U+2029 进行转义。

mb_ereg()mb_eregi() 参数语义的更改

mb_ereg()mb_eregi() 函数的第三个参数 (regs) 现在将在没有匹配项时被设置为空数组。以前,该参数不会被修改。

删除对 sslv2 流的支持

sslv2 流现已从 OpenSSL 中删除。

禁止在编译时已经存在类型化返回值的情况下使用 "return;"

声明了返回值类型的函数中没有参数的 return 语句现在将触发 E_COMPILE_ERROR(除非返回值类型声明为 void),即使 return 语句永远不会被执行。

添加注释

用户贡献的注释 5 notes

love at sickpeople dot se
7 年前
对于从 5.x 迁移到 7.1 的任何人

关于此页面上的“在通过引用赋值期间自动创建元素时的数组排序已更改”

(https://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

7.1 的行为与 PHP 5 相同。只有 7.0 不同。

请参阅 https://3v4l.org/frbUc

<?php

$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
kees at twekaers dot net
7 年前
向后不兼容的更改“空索引运算符不再支持字符串”的影响远不止以下代码中的致命错误

<?php
$a
= "";
$a[] = "hello world";
var_dump($a);
?>

这将在 7.1 中产生致命错误,但在 7.0 或更低版本中将按预期工作,并给出:(无通知,无警告)

array(1) {
[0]=>
string(11) "hello world"
}

但是,以下内容也已更改

<?php
$a
= "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) " h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

?>
m dot r dot sopacua at gmail dot com
7 年前
“OMG!为什么 session.hash_function 被移除了?!老兄!”

https://wiki.php.net/rfc/session-id-without-hashing

好了,帮你省去了搜索的麻烦。
mikem at gmail dot com
6 年前
ArgumentCountError - 这种修改是避免在旧项目中使用这个版本的 主要原因。
david at artefactual dot com
5 年前
关于 ArgumentCountError,PHP 7.1+ 仍然支持带有可变数量参数的用户函数,使用 "func(...$args) {}" 语法,请参见:https://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
To Top