Home  >  Article  >  php教程  >  PHP7.0版本备注

PHP7.0版本备注

WBOY
WBOYOriginal
2016-06-06 19:51:201309browse

这篇文章主要介绍了PHP7.0版本备注,新版本发布在性能方面大大提升,同时在语言特性方面也改变了不少,以下内容是LCT翻译对官方版本升级备注,需要的朋友可以参考

PHP7.0新版本不仅在性能方面大大提升而且在语言特性方面也改变很多,具体讲解请看下文:

PHP7.0版本备注

 
1. 向后不兼容的变化
语言变化

变量处理的变化
间接变量、属性和方法引用现在以从左到右的语义进行解释。一些例子:

$$foo['bar']['baz'] // 解释做 ($$foo)['bar']['baz'] $foo->$bar['baz'] // 解释做 ($foo->$bar)['baz'] $foo->$bar['baz']() // 解释做 ($foo->$bar)['baz']() Foo::$bar['baz']() // 解释做 (Foo::$bar)['baz']()


要恢复以前的行为,需要显式地加大括号:

${$foo['bar']['baz']} $foo->{$bar['baz']} $foo->{$bar['baz']}() Foo::{$bar['baz']}()

全局关键字现在只接受简单变量。像以前的

复制代码 代码如下:


global $$foo->bar;


现在要求如下写法:

复制代码 代码如下:


global ${$foo->bar};


变量或函数调用的前后加上括号不再有任何影响。例如下列代码,,函数调用结果以引用的方式传给一个函数

function getArray() { return [1, 2, 3]; } $last = array_pop(getArray()); // Strict Standards: 只有变量可以用引用方式传递 $last = array_pop((getArray()));


// Strict Standards: 只有变量可以用引用方式传递
现在无论是否使用括号,都会抛出一个严格标准错误。以前在第二种调用方式下不会有提示。

数组元素或对象属性自动安装引用顺序创建,现在的结果顺序将不同。例如:

$array = []; $array["a"] =& $array["b"]; $array["b"] = 1; var_dump($array); 现在结果是 ["a" => 1, "b" => 1],而以前的结果是 ["b" => 1, "a" => 1]

相关的 RFC:

https://wiki.php.net/rfc/uniform_variable_syntax
https://wiki.php.net/rfc/abstract_syntax_tree
 
list() 的变化
list() 不再以反序赋值,例如:

复制代码 代码如下:


list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);


现在结果是 $array == [1, 2, 3] ,而不是 [3, 2, 1]。注意仅赋值顺序变化了,而赋值仍然一致(LCTT 译注:即以前的 list()行为是从后面的变量开始逐一赋值,这样对与上述用法就会产生 [3,2,1] 这样的结果了。)。例如,类似如下的常规用法

复制代码 代码如下:


list($a, $b, $c) = [1, 2, 3];
// $a = 1; $b = 2; $c = 3;


仍然保持当前的行为。

不再允许对空的 list() 赋值。如下全是无效的:

list() = $a; list(,,) = $a; list($x, list(), $y) = $a; list() 不再支持对字符串的拆分(以前也只在某些情况下支持)

如下代码:

复制代码 代码如下:


$string = "xy";
list($x, $y) = $string;


现在的结果是: $x == null 和 $y == null (没有提示),而以前的结果是: $x == "x" 和 $y == "y" 。

此外, list() 现在总是可以处理实现了 ArrayAccess 的对象,例如:

复制代码 代码如下:


list($a, $b) = (object) new ArrayObject([0, 1]);


现在的结果是: $a == 0 和 $b == 1。 以前 $a 和 $b 都是 null。

相关 RFC:


https://wiki.php.net/rfc/fix_list_behavior_inconsistency
 
foreach 的变化
foreach() 迭代不再影响数组内部指针,数组指针可通过 current()/next() 等系列的函数访问。例如:

复制代码 代码如下:


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


现在将指向值 int(0) 三次。以前的输出是 int(1)、int(2) 和 bool(false)。

在对数组按值迭代时,foreach 总是在对数组副本进行操作,在迭代中任何对数组的操作都不会影响到迭代行为。例如:

复制代码 代码如下:


$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}


现在将打印出全部三个元素 (0 1 2),而以前第二个元素 1 会跳过 (0 2)。

在对数组按引用迭代时,对数组的修改将继续会影响到迭代。不过,现在 PHP 在使用数字作为键时可以更好的维护数组内的位置。例如,在按引用迭代过程中添加数组元素:

复制代码 代码如下:


$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}


现在迭代会正确的添加了元素。如上代码输出是 "int(0) int(1)",而以前只是 "int(0)"。

对普通(不可遍历的)对象按值或按引用迭代的行为类似于对数组进行按引用迭代。这符合以前的行为,除了如上一点所述的更精确的位置管理的改进。

对可遍历对象的迭代行为保持不变。

相关 RFC: https://wiki.php.net/rfc/php7_foreach

参数处理的变化
不能定义两个同名的函数参数。例如,下面的方法将会触发编译时错误:

复制代码 代码如下:


public function foo($a, $b, $unused, $unused) {
// ...
}


如上的代码应该修改使用不同的参数名,如:

复制代码 代码如下:


public function foo($a, $b, $unused1, $unused2) {
// ...
}


func_get_arg() 和 func_get_args() 函数不再返回传递给参数的原始值,而是返回其当前值(也许会被修改)。例如:

复制代码 代码如下:


function foo($x) {
$x++;
var_dump(func_get_arg(0));
}


foo(1);
将会打印 "2" 而不是 "1"。代码应该改成仅在调用 func_get_arg(s) 后进行修改操作。

复制代码 代码如下:


function foo($x) {
var_dump(func_get_arg(0));
$x++;
}


或者应该避免修改参数:

复制代码 代码如下:


function foo($x) {
$newX = $x + 1;
var_dump(func_get_arg(0));
}


类似的,异常回溯也不再显示传递给函数的原始值,而是修改后的值。例如:

复制代码 代码如下:


function foo($x) {
$x = 42;
throw new Exception;
}


foo("string");
现在堆栈跟踪的结果是:

复制代码 代码如下:


Stack trace:
#0 file.php(4): foo(42)
#1 {main}


而以前是:

复制代码 代码如下:


Stack trace:
#0 file.php(4): foo('string')
#1 {main}


这并不会影响到你的代码的运行时行为,值得注意的是在调试时会有所不同。

同样的限制也会影响到 debug_backtrace() 及其它检查函数参数的函数。

相关 RFC: https://wiki.php.net/phpng

整数处理的变化
无效的八进制表示(包含大于7的数字)现在会产生编译错误。例如,下列代码不再有效:

$i = 0781; // 8 不是一个有效的八进制数字!
以前,无效的数字(以及无效数字后的任何数字)会简单的忽略。以前如上 $i 的值是 7,因为后两位数字会被悄悄丢弃。

二进制以负数镜像位移现在会抛出一个算术错误:

复制代码 代码如下:


var_dump(1 >> -1);


// ArithmeticError: 以负数进行位移
向左位移的位数超出了整型宽度时,结果总是 0。

复制代码 代码如下:


var_dump(1


以前上述代码的结果依赖于所用的 CPU 架构。例如,在 x86(包括 x86-64) 上结果是 int(1),因为其位移操作数在范围内。

类似的,向右位移的位数超出了整型宽度时,其结果总是 0 或 -1 (依赖于符号):

复制代码 代码如下:


var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)


相关 RFC: https://wiki.php.net/rfc/integer_semantics

字符串处理的变化
包含十六进制数字的字符串不会再被当做数字,也不会被特殊处理。参见例子中的新行为:

复制代码 代码如下:

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn