
在 PHP 7 提出 Uniform Variable Syntax 之前,我们大多数人可能都没有意识到之前版本的 PHP 语法有多么“不一致”。而事实是在 variable-variable 和 variable-properties 的用法上, PHP 之前的表现的确有些混乱。
现在好了, PHP 7 修复了之前所有的语法一致性问题,并提供了一些新的语法,我们逐一看一下它们。
简单来说, PHP 7 采取的 Uniform 方案就是“统一采用从左到右的方式来评估表达式”。记住这个准则,对于我们分析一些看似复杂的表达式很有帮助。我们通过对比一些代码在 PHP 7 和 PHP 5 中的结果,来理解 Uniform 的含义。为了能够清楚的表示同一语法在不同版本 PHP 里的评估顺序,我们使用{}做了标记。
<?php
$$var['key1']['key2'];
// PHP 5.x
${$var['key1']['key2']};
// PHP 7
{$$var}['key1']['key2'];
class Demo {
public $prop;
public __construct() { $this->prop = [ 'key' => 'value' 'closure' => function() { } ]; } }
$var = new Demo;
$var->prop['key'];
// PHP 5.x
$var->{prop['key']};
// PHP 7
{$var->prop}['key'];
$var->prop'key';
// PHP 5.x
$var->{prop['key']}();
// PHP 7
{$var->prop}'key';
ClassName::$var'key';
// PHP 5.x
ClassName::{$var['key']}();
// PHP 7
(ClassName::$var)'key';
除了对已有语法的一致性调整, Uniform Variable Syntax 还为我们带来了很多新的语法。
调用函数和访问属性
如果函数返回一个包含 closure 的数组,我们可以这样掉用它:
<?php foo()['bar'](); 如果数组中的对象有特定的属性,我们可以这样访问它:
<?php [$obj1, $obj2][3]->prop; 如果函数返回一个字符串,我们可以使用"{字符下标}"来访问字符串中的字符:
<?php retString(){1}; 除了组合各种表达式之外,我们还可以嵌套使用 ::。
如果 Foo::bar()返回一个静态类的名字,我们可以这样访问它的静态成员或者调用静态方法:
<?php
Foo:bar()::$staticProp; Foo:bar()::$staticMethod(); 只要表达式返回了一个 callable 对象,我们可以直接调用它们:
<?php foo()(); Foo::bar()(); $foo->bar()(); 接下来,我们来看一些更自由的表达方式:我们根据表达式 expression 评估的结果,后面可以接各种访问属性和函数调用的形式:
<?php // (expression) is array (expression)['key']; // (expression) is a class object (expression)->foo(); (expression)->prop; // (expression) is a class name (expression)::$foo; (expression)::foo(); // (expression) is a string (expression){0}; // (expression) is a callable object (expression)(); 我们甚至可以对一个 scalar type 进行解引用,如果字符串'ClassName'代表一个类名称,我们可以直接访问这个类的静态成员:
<?php 'ClassName'::staticMethod(); 我们还可以用数组的形式来调用类的静态方法和成员方法:
<?php ['ClassName', 'staticMethod'](); [$obj, 'method'](); 在 PHP 7 里,有一个和 PHP 5 不兼容的语法,会导致解析错误。当我们定义一个 global 变量的时候, PHP 7 不允许使用存在二义性的表达式,例如:
<?php global $$foo->bar; // Wrong in PHP 7 会导致 PHP 7 解析错误,我们必须使用{}来明确定义解析顺序:
<?php global ${$foo->bar}; 1 yxzblue 2015-12-22 17:48:07 +08:00 js 的影子越来越重了 |