> For the complete documentation index, see [llms.txt](https://php7.shujuwajue.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://php7.shujuwajue.com/php-70x-xin-te-xing/bu-xiang-hou-jian-rong-de-bian-geng.md).

# 补充\*不向后兼容的变更

## 目录:

* E\_STRICT 警告级别变更
* 关于list()处理方式的变更
  * 常用的方式
  * list() 不再以反向的顺序来进行赋值
  * 空的list()赋值支持已经被移除
  * list() string 不再能解开
* 当引用分配时自动创建元素的数组排序已更改
* *global*只接受简单变量
* 非**Traversable**对象的遍历(本文无座介绍,详见[链接](http://php.net/manual/zh/migration70.incompatible.php) , 搜索"非**Traversable**对象的遍历")
* 函数参数附近的括号不再影响行为
* foreach的变化
  * foreach不再改变内部数组指针
  * foreach通过值遍历时，操作的值为数组的副本
  * foreach通过引用遍历时，有更好的迭代特性
* string处理上的调整
  * 十六进制字符串不再被认为是数字
  * *\u{*&#x53EF;能引起错误
* 被移除的函数（Removed functions）
  * [call\_user\_method()](https://www.gitbook.com/book/xiaoxiami/php-7/edit#) 和 [call\_user\_method\_array()](https://www.gitbook.com/book/xiaoxiami/php-7/edit#)
  * 所有的 ereg\* 函数
  * [mcrypt](https://www.gitbook.com/book/xiaoxiami/php-7/edit#) 别名
  * 所有 ext/mysql 函数
  * [intl](https://www.gitbook.com/book/xiaoxiami/php-7/edit#) 别名
  * set\_magic\_quotes\_runtime()
  * set\_socket\_blocking()
  * dl() in PHP-FPM
  * GD Type1 functions
* 被移除掉的 INI 配置指令
  * 被移除的功能
* 其他不向后兼容的变更
  * new 操作符创建的对象不能以引用方式赋值给变量
  * 无效的类、接口以及 trait 命名
  * 移除了 ASP 和 script PHP 标签
  * 从不匹配的上下文发起调用
  * yield 变更为右联接运算符
  * 函数定义不可以包含多个同名参数
  * Switch 语句不可以包含多个 default 块
  * 在函数中检视参数值会返回当前的值
  * $HTTP\_RAW\_POST\_DATA被移除
  * INI 文件中#注释格式被移除
  * JSON 扩展已经被 JSOND 取代
  * 在数值溢出的时候，内部函数将会失败
  * 自定义会话处理器的返回值修复
  * 相等的元素在排序时的顺序问题

## E\_STRICT 警告级别变更

原有的`E_STRICT`警告都被迁移到其他级别。`E_STRICT`常量会被保留，所以调用*error\_reporting(E\_ALL|E\_STRICT)*&#x4E0D;会引发错误.

举例(以静态方式调用实例方法):

```php
<?php
error_reporting(E_ALL|E_STRICT);
class mycls{

  function func()
  {
  echo "none static";
  }

}

mycls::func();
```

php7 中则会印发新的`E_DEPRECATED 级别的错误`

```
eprecated: Non-static method mycls::func() should not be called statically in xxxx
```

| **场景**                  | **新的级别/行为**    |
| ----------------------- | -------------- |
| 将资源类型的变量用作键来进行索引        | `E_NOTICE`     |
| 抽象静态方法                  | 不再警告，会引发错误     |
| 重复定义构造器函数               | 不再警告，会引发错误     |
| 在继承的时候，方法签名不匹配          | `E_WARNING`    |
| 在两个 trait 中包含相同的（兼容的）属性 | 不再警告，会引发错误     |
| 以非静态调用的方式访问静态属性         | `E_NOTICE`     |
| 变量应该以引用的方式赋值            | `E_NOTICE`     |
| 变量应该以引用的方式传递（到函数参数中）    | `E_NOTICE`     |
| 以静态方式调用实例方法             | `E_DEPRECATED` |

## 关于list()处理方式的变更

详见官方: [关于list()处理方式的变更 ](http://php.net/manual/zh/migration70.incompatible.php)

### 常用的方式:

```php
<?php
$str = "China|Chinese";

list($country, $language) = explode('|', $str);

echo 'country:' . $country;
echo 'language:' . $language;
```

### list() 不再以反向的顺序来进行赋值.

官方说明:

PHP7 现在会按照变量定义的顺序来给他们进行赋值，而非反过来的顺序。 通常来说，这只会影响list() 与数组的\[]操作符一起使用的案例，如下所示：

```php
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>
```

Output of the above example in PHP 5:

```
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}
```

Output of the above example in PHP 7:

```
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
```

总之，我们推荐不要依赖[list()](http://php.net/manual/zh/function.list.php)的赋值顺序，因为这是一个在未来也许会变更的实现细节。

### 空的list () 赋值支持已经被移除

[list()](http://php.net/manual/zh/function.list.php)结构在PHP 7 现在不再能是空的。如下的例子不再被允许：

```php
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>
```

### **list() string 不再能解开**

如下代码,在php 5.x 当中顺利运行,并输出相应的 a b 值 ,但是在php7 中不会输出 如下:

```php
<?php
$str = 'ab';
list($a, $b) = $str;
echo $a;
echo $b;
```

list() 不再能解开字符串（string）变量。 你可以使用str\_split()来代替它,如下代码:

> str\_split() 函数把字符串分割到数组中。 第二个可选参数支持规定每个数组元素的长度。默认是 1。

```php
<?php
$str = 'ab';
list($a, $b) = str_split($str);
echo $a;
echo $b;
```

## 当引用分配时自动创建元素的数组排序已更改

数组中的元素的顺序已更改，这些元素在引用引用赋值时自动创建。例如:

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

Output of the above example in PHP 5:

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

Output of the above example in PHP 7:

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

## *global*只接受简单变量

可变变量不再能够与 global 关键字一起使用。 如果在PHP7 中需要的话可以使用圆括号来模拟之前的行为。

```php
<?php
function f() {
    // Valid in PHP 5 only.
    global $$foo->bar;

    // Valid in PHP 5 and 7.
    global ${$foo->bar};
}
?>
```

作为一个通用的准则，[*global*](http://php.net/manual/zh/language.variables.scope.php#language.variables.scope.global)一个除了裸的变量以外的任何东西都是不被推荐的。

## 函数参数附近的括号不再影响行为

在PHP 7中(官方标注为php5,经过测试php5中无报错,报错在php7中,故作修改)，当函数参数通过引用传递时，围绕函数参数使用冗余括号可以保持严格的标准警告。警告将永远发出。

```php
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);

function getArray() {
    return [1, 2, 3];
}

function squareArray(array &$a) {
    foreach ($a as &$v) {
        $v **= 2;
    }
}

// Generates a warning in PHP 7.
squareArray((getArray()));
```

以上栗子会报错:

```
Notice: Only variables should be passed by reference in xxxxx
```

## foreach的变化

foreach发生了细微的变化，控制结构， 主要围绕阵列的内部数组指针和迭代处理的修改。

### foreach不再改变内部数组指针

在PHP7之前，当数组通过foreach迭代时，数组指针会移动。现在开始，不再如此，见下面代码:

```php
<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}
?>
```

Output of the above example in PHP 5:

```
int(1)
int(2)
bool(false)
```

Output of the above example in PHP 7:

```
int(0)
int(0)
int(0)
```

### foreach通过值遍历时，操作的值为数组的副本

当默认使用通过值遍历数组时，foreach实际操作的是数组的迭代副本，而非数组本身。这就意味着，foreach 中的操作不会修改原数组的值。

### foreach通过引用遍历时，有更好的迭代特性

当使用引用遍历数组时，现在foreach在迭代中能更好的跟踪变化。例如，在迭代中添加一个迭代值到数组中，参考下面的代码：

```php
<?php
$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
?>
```

Output of the above example in PHP 5:

```
int(0)
```

Output of the above example in PHP 7:

```
int(0)
int(1)
```

## string处理上的调整

### 十六进制字符串不再被认为是数字

含十六进制字符串不再被认为是数字(**也就是十六进制的字符串不会转成十进制数字进行比较,而是做一个字符串**)。例如：

```php
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>
```

Output of the above example in PHP 5:

```
bool(true)
bool(true)
int(15)
string(2) "oo"
```

Output of the above example in PHP 7:

```
bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"
```

解决办法:

filter\_var() 函数可以用于检查一个 string 是否含有十六进制数字,并将其转换为integer:

```php
<?php
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
    throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>
```

### *\u{*&#x53EF;能引起错误

由于新的[Unicode codepoint escape syntax](http://php.net/manual/zh/migration70.new-features.php#migration70.new-features.unicode-codepoint-escape-syntax) 语法， 紧连着无效序列并包含`\u{`的字串可能引起致命错误。 为了避免这一报错，应该避免反斜杠开头。

## 被移除的函数（Removed functions）

### [call\_user\_method()](http://php.net/manual/zh/function.call-user-method.php) 和 [call\_user\_method\_array()](http://php.net/manual/zh/function.call-user-method-array.php)

这两个函数从PHP 4.1.0开始被废弃，应该使用[call\_user\_func()](http://php.net/manual/zh/function.call-user-func.php)和[call\_user\_func\_array()](http://php.net/manual/zh/function.call-user-func-array.php)。 你也可以考虑使用[变量函数](http://php.net/manual/zh/functions.variable-functions.php)或者[*...*](http://php.net/manual/zh/functions.arguments.php#functions.variable-arg-list.new)操作符。

### 所有的 ereg\* 函数

所有[ereg](http://php.net/manual/zh/book.regex.php)系列函数被删掉了。[PCRE](http://php.net/manual/zh/book.pcre.php)作为推荐的替代品。

### [mcrypt](http://php.net/manual/zh/book.mcrypt.php)别名

已废弃的[mcrypt\_generic\_end()](http://php.net/manual/zh/function.mcrypt-generic-end.php)函数已被移除，请使用[mcrypt\_generic\_deinit()](http://php.net/manual/zh/function.mcrypt-generic-deinit.php)代替。

此外，已废弃的[mcrypt\_ecb()](http://php.net/manual/zh/function.mcrypt-ecb.php),[mcrypt\_cbc()](http://php.net/manual/zh/function.mcrypt-cbc.php),[mcrypt\_cfb()](http://php.net/manual/zh/function.mcrypt-cfb.php)和[mcrypt\_ofb()](http://php.net/manual/zh/function.mcrypt-ofb.php)函数已被移除，请配合恰当的`MCRYPT_MODE_*`常量来使用[mcrypt\_decrypt()](http://php.net/manual/zh/function.mcrypt-decrypt.php)进行代替。

### 所有 ext/mysql 函数

所有[ext/mysql](http://php.net/manual/zh/book.mysql.php)函数已被删掉了。 如何选择不同的 MySQL API，详情请见[选择 MySQL API](http://php.net/manual/zh/mysqlinfo.api.choosing.php)。

### 所有 ext/mssql 函数

所有[ext/mssql](http://php.net/manual/zh/book.mssql.php)函数已被删掉了。 替代品的列表，参见[MSSQL 介绍](http://php.net/manual/zh/intro.mssql.php)。

### [intl](http://php.net/manual/zh/book.intl.php)别名

已废弃的[datefmt\_set\_timezone\_id()](http://php.net/manual/zh/intldateformatter.settimezoneid.php)和[IntlDateFormatter::setTimeZoneID()](http://php.net/manual/zh/intldateformatter.settimezoneid.php)函数已被移除，请使用[datefmt\_set\_timezone()](http://php.net/manual/zh/intldateformatter.settimezone.php)与[IntlDateFormatter::setTimeZone()](http://php.net/manual/zh/intldateformatter.settimezone.php)代替。

### [set\_magic\_quotes\_runtime()](http://php.net/manual/zh/function.set-magic-quotes-runtime.php)

[set\_magic\_quotes\_runtime()](http://php.net/manual/zh/function.set-magic-quotes-runtime.php), 和它的别名[magic\_quotes\_runtime()](http://php.net/manual/zh/function.magic-quotes-runtime.php)已被移除. 它们在PHP 5.3.0中已经被废弃,并且 在[in PHP 5.4.0](http://php.net/manual/zh/migration54.incompatible.php)也由于魔术引号的废弃而失去功能。

### [set\_socket\_blocking()](http://php.net/manual/zh/function.set-socket-blocking.php)

已废弃的[set\_socket\_blocking()](http://php.net/manual/zh/function.set-socket-blocking.php)函数已被移除，请使用[stream\_set\_blocking()](http://php.net/manual/zh/function.stream-set-blocking.php)代替。

### [dl()](http://php.net/manual/zh/function.dl.php) in PHP-FPM

[dl()](http://php.net/manual/zh/function.dl.php)在 PHP-FPM 不再可用，在 CLI 和 embed SAPIs 中仍可用。

### [GD](http://php.net/manual/zh/book.image.php) Type1 functions

PostScript Type1字体的支持已经从GD扩展删除，导致以下功能的去除：

* [imagepsbbox()](http://php.net/manual/zh/function.imagepsbbox.php)
* [imagepsencodefont()](http://php.net/manual/zh/function.imagepsencodefont.php)
* [imagepsextendfont()](http://php.net/manual/zh/function.imagepsextendfont.php)
* [imagepsfreefont()](http://php.net/manual/zh/function.imagepsfreefont.php)
* [imagepsloadfont()](http://php.net/manual/zh/function.imagepsloadfont.php)
* [imagepsslantfont()](http://php.net/manual/zh/function.imagepsslantfont.php)
* [imagepstext()](http://php.net/manual/zh/function.imagepstext.php)

推荐使用 TrueType 字体和相关的函数作为替代。

## 被移除掉的 INI 配置指令

### 被移除的功能

以下 INI 配置指令已经被移除，同时移除的还有其对应的功能

* [`always_populate_raw_post_data`](http://php.net/manual/zh/ini.core.php#ini.always-populate-raw-post-data)
* [`asp_tags`](http://php.net/manual/zh/ini.core.php#ini.asp-tags)

`xsl.security_prefs`

`xsl.security_prefs`指令被移除 在预处理的时候，取而代之的方法[XsltProcessor::setSecurityPrefs()](http://php.net/manual/zh/xsltprocessor.setsecurityprefs.php)应该被调用到

## 其他不向后兼容的变更

### new 操作符创建的对象不能以引用方式赋值给变量

[*new*](http://php.net/manual/zh/language.oop5.basic.php#language.oop5.basic.new)语句创建的对象不能 以引用的方式赋值给变量。

```php
<?php
class C {}
$c =& new C;
?>
```

Output of the above example in PHP 5:

```php
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3
```

Output of the above example in PHP 7:

```
Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3
```

### 无效的类、接口以及 trait 命名

不能以下列名字来命名类、接口以及 trait：

* [bool](http://php.net/manual/zh/language.types.boolean.php)
* [int](http://php.net/manual/zh/language.types.integer.php)
* [float](http://php.net/manual/zh/language.types.float.php)
* [string](http://php.net/manual/zh/language.types.string.php)
* `NULL`
* `TRUE`
* `FALSE`

此外，也不要使用下列的名字来命名类、接口以及 trait。虽然在 PHP 7.0 中， 这并不会引发错误， 但是这些名字是保留给将来使用的。

* [resource](http://php.net/manual/zh/language.types.resource.php)
* [object](http://php.net/manual/zh/language.types.object.php)
* [mixed](http://php.net/manual/zh/language.pseudo-types.php#language.types.mixed)
* numeric

### 移除了 ASP 和 script PHP 标签

使用类似 ASP 的标签，以及 script 标签来区分 PHP 代码的方式被移除。 受到影响的标签有：

**被移除的 ASP 和 script 标签**

| 开标签                       | 闭标签         |
| ------------------------- | ----------- |
| `<%`                      | `%>`        |
| `<%=`                     | `%>`        |
| `<script language="php">` | `</script>` |

### 从不匹配的上下文发起调用

在不匹配的上下文中以静态方式调用非静态方法，[在 PHP 5.6 中已经废弃](http://php.net/manual/zh/migration56.deprecated.php#migration56.deprecated.incompatible-context)， 但是在 PHP 7.0 中， 会导致被调用方法中未定&#x4E49;*$this*变量，以及此行为已经废弃的警告。

```php
<?php
class A {
    public function test() { var_dump($this); }
}

// 注意：并没有从类 A 继承
class B {
    public function callNonStaticMethodOfA() { A::test(); }
}

(new B)->callNonStaticMethodOfA();
?>
```

Output of the above example in PHP 5.6:

```
Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}
```

Output of the above example in PHP 7:

```
Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL
```

### [yield](http://php.net/manual/zh/language.generators.syntax.php#control-structures.yield) 变更为右联接运算符

在使用 yield 关键字的时候，不再需要括号， 并且它变更为右联接操作符，其运算符优先级介于 print 和 => 之间。 这可能导致现有代码的行为发生改变：

```php
<?php
echo yield -1;
// 在之前版本中会被解释为：
echo (yield) - 1;
// 现在，它将被解释为：
echo yield (-1);

yield $foo or die;
// 在之前版本中会被解释为：
yield ($foo or die);
// 现在，它将被解释为：
(yield $foo) or die;
?>
```

可以通过使用括号来消除歧义。

### 函数定义不可以包含多个同名参数

在函数定义中，不可以包含两个或多个同名的参数。 例如，下面代码中的函数定义会触发`E_COMPILE_ERROR`错误：

```php
<?php
function foo($a, $b, $unused, $unused) {
    //
}
?>
```

### Switch 语句不可以包含多个 default 块

在 switch 语句中，两个或者多个 default 块的代码已经不再被支持。 例如，下面代码中的 switch 语句会触发`E_COMPILE_ERROR`错误：

```php
<?php
switch (1) {
    default:
    break;
    default:
    break;
}
?>
```

### 在函数中检视参数值会返回*当前*的值

当在函数代码中使用 [func\_get\_arg()](http://php.net/manual/zh/function.func-get-arg.php) 或 [func\_get\_args()](http://php.net/manual/zh/function.func-get-args.php) 函数来检视参数值， 或者使用 [debug\_backtrace()](http://php.net/manual/zh/function.debug-backtrace.php) 函数查看回溯跟踪， 以及在异常回溯中所报告的参数值是指参数当前的值（有可能是已经被函数内的代码改变过的值）， 而不再是参数被传入函数时候的原始值了。

```php
<?php
function foo($x) {
    $x++;
    var_dump(func_get_arg(0));
}
foo(1);?>
```

Output of the above example in PHP 5:

```
1
```

Output of the above example in PHP 7:

```
2
```

### [$HTTP\_RAW\_POST\_DATA](http://php.net/manual/zh/reserved.variables.httprawpostdata.php)被移除

不再提供 [$HTTP\_RAW\_POST\_DATA](http://php.net/manual/zh/reserved.variables.httprawpostdata.php) 变量。 请使用 [*php://input*](http://php.net/manual/zh/wrappers.php.php#wrappers.php.input) 作为替代。

### INI 文件&#x4E2D;*#*&#x6CE8;释格式被移除

在 INI 文件中，不再支持&#x4EE5;*#*&#x5F00;始的注释行， 请使&#x7528;*;*（分号）来表示注释。 此变更适用于php.ini以及用[parse\_ini\_file()](http://php.net/manual/zh/function.parse-ini-file.php)和[parse\_ini\_string()](http://php.net/manual/zh/function.parse-ini-string.php)函数来处理的文件。

### JSON 扩展已经被 JSOND 取代

JSON 扩展已经被 JSOND 扩展取代。 对于数值的处理，有以下两点需要注意的： 第一，数值不能以点号（.）结束 （例如，数值*34.*&#x5FC5;须写作*34.0*或*34*）。 第二，如果使用科学计数法表示数值，*e*前面必须不是点号（.） （例如，*3.e3*必须写作*3.0e3*或*3e3*）。 另外，空字符串不再被视作有效的 JSON 字符串。

### 在数值溢出的时候，内部函数将会失败

将浮点数转换为整数的时候，如果浮点数值太大，导致无法以整数表达的情况下， 在之前的版本中，内部函数会直接将整数截断，并不会引发错误。 在 PHP 7.0 中，如果发生这种情况，会引发 E\_WARNING 错误，并且返回`NULL`。

### 自定义会话处理器的返回值修复

在自定义会话处理器中，如果函数的返回值不是`FALSE`，也不&#x662F;*-1*， 会引发致命错误。现在，如果这些函数的返回值不是布尔值，也不&#x662F;*-1*或者*0*，函数调用结果将被视为失败，并且引发 E\_WARNING 错误。

### 相等的元素在排序时的顺序问题

由于内部排序算法进行了提升， 可能会导致对比时被视为相等的多个元素之间的顺序不稳定。

> 在对比时被视为相等的多个元素之间的排序顺序是不可信赖的，即使是相等的两个元素， 他们的位置也可能被排序算法所改变。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
