V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yiling
V2EX  ›  PHP

PHP7 最新语法实践分享——Uniform Variable Syntax(高亮)

  •  
  •   yiling · 2015-12-22 17:53:10 +08:00 · 2432 次点击
    这是一个创建于 3049 天前的主题,其中的信息可能已经有所发展或是发生改变。

    泊学原文链接
    泊学实操视频

    在 PHP 7 提出 Uniform Variable Syntax 之前,我们大多数人可能都没有意识到之前版本的 PHP 语法有多么“不一致”。而事实是在 variable-variable 和 variable-properties 的用法上, PHP 之前的表现的确有些混乱。

    现在好了, PHP 7 修复了之前所有的语法一致性问题,并提供了一些新的语法,我们逐一看一下它们。

    Consistency Fixes

    简单来说, 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']();
    

    PHP 7 中的新语法

    除了对已有语法的一致性调整, 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']();
    

    A parse error in PHP 7

    在 PHP 7 里,有一个和 PHP 5 不兼容的语法,会导致解析错误。当我们定义一个 global 变量的时候, PHP 7 不允许使用存在二义性的表达式,例如:

    <?php
    
        global $$foo->bar; // Wrong in PHP 7
    

    会导致 PHP 7 解析错误,我们必须使用{}来明确定义解析顺序:

    <?php
    
        global ${$foo->bar};
    
    2 条回复    2015-12-26 16:25:24 +08:00
    349865361
        1
    349865361  
       2015-12-24 09:59:33 +08:00
    还有再类里面声明对象变量的时候可以直接拼接常量以前是不行的
    public $url = ROOT . '/url';
    yiling
        2
    yiling  
    OP
       2015-12-26 16:25:24 +08:00
    谢谢补充,哈哈!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3012 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:50 · PVG 21:50 · LAX 06:50 · JFK 09:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.