扫码一下
查看教程更方便
PHP 7 现在使用了抽象语法树来解析源代码。这使得许多由于之前的PHP的解释器的限制所不可能实现的改进得以实现。 但出于一致性的原因导致了一些特殊例子的变动,而这些变动打破了向后兼容。 在这一章中将详细介绍这些例子。
对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析,而不是之前的混杂着几个特殊案例的情况。 下面这张表说明了这个解析顺序的变化。
表达式 | PHP 5 的解析方式 | PHP 7 的解析方式 |
---|---|---|
$$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']() |
使用了旧的从右到左的解析顺序的代码必须被重写,明确的使用大括号来表明顺序(参见上表中间一列)。 这样使得代码既保持了与PHP 7.x的前向兼容性,又保持了与PHP 5.x的后向兼容性。
这同样影响了 global 关键字。如果需要的话可以使用大括号来模拟之前的行为。
<?php
function f() {
// Valid in PHP 5 only.
global $$foo->bar;
// Valid in PHP 5 and 7.
global ${$foo->bar};
}
?>
list() 现在会按照变量定义的顺序来给他们进行赋值,而非反过来的顺序。 通常来说,这只会影响list() 与数组的[]操作符一起使用的案例,如下所示:
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>
以上程序在 PHP 5 中的输出:
array(3) {
[0]=>
int(3)
[1]=>
int(2)
[2]=>
int(1)
}
以上程序在 PHP 7 中的输出:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
总之,我们推荐不要依赖list()的赋值顺序,因为这是一个在未来也许会变更的实现细节。
list() 结构现在不再能是空的。如下的例子不再被允许:
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>
list() 不再能拆解字符串(string)变量。 可以使用str_split()来代替。
在 PHP 5中,在以引用方式传递函数参数时,使用冗余的括号对可以隐匿严格标准 的警告。现在,这个警告总会触发。
<?php
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 /tmp/test.php on line 13