变量处理的变化

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() 不再以反向的顺序来进行赋值

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()赋值支持已经被移除

list() 结构现在不再能是空的。如下的例子不再被允许:

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

list()不再能拆解 string

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

查看笔记

扫码一下
查看教程更方便