# 补充:不向后兼容的变更

> 参考：[不向后兼容的变更](https://secure.php.net/manual/zh/migration71.incompatible.php)

## 不向后兼容的变更

### 当传递参数过少时将抛出错误

在过去如果我们调用一个用户定义的函数时，提供的参数不足，那么将会产生一个警告(warning)。 现在，这个警告被提升为一个错误异常(Error exception)。这个变更仅对用户定义的函数生效， 并不包含内置函数。例如：

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

Output of the above example in PHP 5.5:

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

### 禁止动态调用范围内功能

对某些函数的动态调用被禁止(以`$func()`或`array_map('extract', ...)`等形式)。这些函数可以检查或修改另一个范围，并呈现出模糊和不可靠的行为。其职能如下:

* [assert()](https://php.net/manual/zh/function.assert.php) - 用一个字符串作为第一个参数
* [compact()](https://php.net/manual/zh/function.compact.php)
* [extract()](https://php.net/manual/zh/function.extract.php)
* [func\_get\_args()](https://php.net/manual/zh/function.func-get-args.php)
* [func\_get\_arg()](https://php.net/manual/zh/function.func-get-arg.php)
* [func\_num\_args()](https://php.net/manual/zh/function.func-num-args.php)
* [get\_defined\_vars()](https://php.net/manual/zh/function.get-defined-vars.php)
* [mb\_parse\_str()](https://php.net/manual/zh/function.mb-parse-str.php) - 有一个参数
* [parse\_str()](https://php.net/manual/zh/function.parse-str.php) - 有一个参数

```php
<?php
(function () {
    'func_num_args'();
})();
```

以上例程会输出：

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

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

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

* void
* iterable &#x20;

### 数值串转换现在尊重科学符号

数值操作和数值转换现在要尊重科学符号。这还包括(int)cast操作，以及以下函数:intval()(在这里的基础是10)、settype()、decbin()、decbin()和dechex()。

### 修复mt\_rand()算法

mt\_rand()现在默认使用Mersenne Twister算法的固定版本。如果依赖于mt\_srand()的确定性输出，则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\_log用syslog值进行更改

如果将error\_log ini设置设置为syslog，则将PHP错误级别映射到syslog错误级别。这将在错误日志中提供更细的差异，与前面的方法相反，所有的错误都只在通知级别上记录。

在不完整的对象上不再调用析构方法

析构方法在一个不完整的对象（例如在构造方法中抛出一个异常）上将不再会被调用。

### call\_user\_func()不再支持对传址的函数的调用

[call\_user\_func()](https://php.net/manual/zh/function.call-user-func.php)现在在调用一个以引用作为参数的函数时将始终失败。

### 字符串不再支持空索引操作符 The empty index operator is not supported for strings anymore

对字符串使用一个空索引操作符（例&#x5982;*$str\[] = $x*）将会抛出一个致命错误， 而不是静默地将其转为一个数组。

### ini配置项移除

下列ini配置项已经被移除：

* `session.entropy_file`
* `session.entropy_length`
* `session.hash_function`
* `session.hash_bits_per_character`&#x20;

### 在引用赋值过程中自动创建元素的数组顺序发生了变化

数组中元素的顺序已经发生了变化，当这些元素通过引用被引用的赋值自动创建时。例如:

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

Output of the above example in PHP 7.0:

array(2) {

```
["a"]=
>
&
int(1)
  ["b"]=
>
&
int(1)
}
```

Output of the above example in PHP 7.1:

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

### 等元素的排序 Sort order of equal elements

内部排序算法得到了改进，其结果可能是不同的元素顺序，比之前的相等。

> 不要依赖于元素的顺序，因为元素的顺序是相等的;它可能随时变化。

### Error message for E\_RECOVERABLE errors

The error message for E\_RECOVERABLE errors has been changed from "Catchable fatal error" to "Recoverable fatal error".

### unserialize() 的`$options`参数

unserialize()的`$options`参数的allowed\_classes元素现在被严格输入，即如果给定数组或布尔值之外的其他任何东西，unserialize()将返回FALSE并发出E\_WARNING。

### DateTime构造函数包含微秒

[DateTime](https://php.net/manual/zh/class.datetime.php)和[DateTimeImmutable](https://php.net/manual/zh/class.datetimeimmutable.php)不变现在正确地融合了从当前时间构建的微秒，无论是显式的还是相对的字符串。“下个月的第一天”)。这意味着对两个新创建的实例进行简单的比较，现在更有可能返回**FALSE**而不是**TRUE**:

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

### 错误异常的致命错误转换

详见：[官方](https://secure.php.net/manual/zh/migration71.incompatible.php) ,搜索：Fatal errors to**Error**exceptions conversions

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

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

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

### JSON编码和解码

在编码双精度时，serialize\_precision ini设置现在控制序列化精度。

现在解码一个空的键会导致一个空的属性名，而不是一个属性名。

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

以上例程的输出类似于：

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

当向[json\_encode()](https://php.net/manual/zh/function.json-encode.php)提供JSON\_UNESCAPED\_UNICODE标志时，现在转义了U + 2028和U + 2029的序列。

### 对mb\_ereg()和mb\_eregi()参数语义的更改

如果没有匹配，则将把第三个参数设置为mb\_ereg()和mb\_eregi()函数(regs)，现在将被设置为空数组。Formely，参数不会被修改。

### 停止支持sslv2流

sslv2流现在已经在OpenSSL中被删除了。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://php7.shujuwajue.com/php-71x-xin-te-xing/bu-51453a-bu-xiang-hou-jian-rong-de-bian-geng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
