Press "Enter" to skip to content

PHP5.4新特性-解引用实例化

在以前的PHP中, 我们并不能直接去操作一个对象实例化的结果:

<?php
(new Foo())->show();  //PHP Parse error:  syntax error, unexpected T_OBJECT_OPERATOR

我们只能, 把实例化结果先保存起来, 然后再调用:

$a = new Foo();
$a->show();

关于这个改进, 已经有很多人提出过request, 但是因为实现的问题, 一直没有加入PHP.
这点上, 我解释下, PHP的语法分析系统, 是一个历史悠久的系统, 在这个蛮长的的历史中, 不停的修修补补, 或多或少的会造成一些特定的特性. 而如果要重写, 继耗时, 又耗力, 并且很难做到和现在的完全兼容, 所以我想, 要完全重写, 那也只能是PHP6了(替开发组宣布一下, PHP6目前已经停止开发, 也暂时不会有这种提法)
而, 如果采用修补的方式, 就会引入一个无法解决的移近/归约冲突, 我之前也尝试过实现这个特性, 但是因为遇到这个问题, 所以没有提交..
不过, 随着对这个特性要求的增多, 慢慢的, 大家觉得, 即使多一个移近/归约冲突,,,, 也没啥吧. 嘿嘿, 所以呢:
现在, 这个特性终于在Felipe(Instance and method call/property access)的工作下, 得到了支持, 现在我们就可以书写如下的语法了:

<?php
(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]

你也许注意到了, 所有的实例化式都需要用括号括起来, 是的, 如果不这样, 那么首先, 会有如下的冲突语法:

new $bar->y->x;

此时, 就会有矛盾, 到底是(new $bar)->y呢, 还是(new $bar->y)->x呢.
另外一个原因, 也是因为PHP目前的语法系统, 如果采用不加括号的做法, 那么就会更多的引入一个移近/归约冲突.
不过我相信这个括号也没什么, 起码看起来也更清晰一些.
说到这里, 插个题外话, 我很好奇, C++的语法分析, 那得有多少已知的无法解决的"移近/归约"冲突啊, 有知道的朋友么? 呵呵. (后记, gcc从3.0开始不再使用lex/yacc, 不过从gcc-2.95.1的代码中, 我们可以发现, gcc的已知无法解决的移近/归约冲突为: 51(%expect 51 in gcc-2.95.1/gcc/c-parse.y), 呵呵)
目前, 5.4RC1已经发布, 大家有兴趣的, 可以提早试用, 也帮PHP做做测试:) PHP 5.4RC1, enjoy!
不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.
谢谢
更多更新信息, 请关注: Changelog

19 Comments

  1. ChangVGolt
    ChangVGolt August 1, 2015

    I do not know whether it’s just me or if everybody else encountering problems with your blog.
    It appears as if some of the text on your content are running off the screen. Can someone else please provide feedback and let me know if this is
    happening to them as well? This might be a issue with my browser because I’ve had
    this happen previously. Appreciate it

  2. JunsGo
    JunsGo December 8, 2011

    @雪候鸟
    明白了,谢谢

  3. kakalong
    kakalong December 1, 2011

    good job, 啥时候能用上5.4啊

  4. 雪候鸟
    雪候鸟 November 28, 2011

    @JunsGo +:至少一个, *:0个或多个.

  5. JunsGo
    JunsGo November 28, 2011

    关于preg_replace这个函数奇怪的东一点
    $name = ‘Collector g Minerals ‘;
    echo preg_replace(‘/[\s]+/’,’-‘,$name);
    //output “Collector-g-Minerals-“这个是正确的,但是用
    echo preg_replace(‘/[\s]*/’,’-‘,$name);
    //output “-C-o-l-l-e-c-t-o-r–g–M-i-n-e-r-a-l-s–“会在每个字左右都放一个”-“不知道是为什么??

  6. hzj629206
    hzj629206 November 24, 2011

    如果new和->都算操作符,根据操作符结合性和优先级是可以解释不加括号的情况吧?

  7. 李惟
    李惟 November 15, 2011

    看上去想JS中的闭包,我觉得还是蛮清晰的。

  8. 朱宝祥
    朱宝祥 November 14, 2011

    囧~我真菜~~~

  9. deloz
    deloz November 14, 2011

    能实现这种吗?
    class Foo(){
    public function show();
    }
    $a = new Foo();
    $b = ‘show’;
    $a[$b]();

  10. 雪候鸟
    雪候鸟 November 13, 2011

    @Dennis 这个已经实现了, 看我之前的blog 🙂

  11. Dennis
    Dennis November 13, 2011

    我希望 “on the fly array dereference” 可以将来实现。
    比如所:
    function test()
    { return array(1,2,3); }
    test()[0]; // 1
    test()[1]; // 2

  12. 神仙
    神仙 November 11, 2011

    5.4多的这两特性可以少写一行代码,少个临时变量。
    话说,咱换个链接吧。

  13. 巫山霏云
    巫山霏云 November 11, 2011

    原来只是暂停开发了啊,我说呢……
    5.3应该进入成熟期了吧,不知道5.4会怎样

  14. Liuxd
    Liuxd November 11, 2011

    其实相比新特性,我跟期待能把老毛病改改。
    PHP6怎么暂停了啊?还指望能像Python3那样抛掉包袱重新开始呢。PHP现在命名太乱,还有一堆函数别名也比较讨厌,其实把这些货搞掉就舒服多了。

  15. blue5tar
    blue5tar November 11, 2011

    有函数支持吗
    function func(){
    return new cls();
    //return array(1,2);
    }
    func()->property;
    func()[0];
    这种!!

  16. 雪候鸟
    雪候鸟 November 11, 2011

    @tomheng 是暂时不开发了. 目前要维护5.3和5.4俩个分支.

  17. tomheng
    tomheng November 11, 2011

    PHP6停止开发是什么意思,是指开发结束,还是放弃了不开放了?

  18. venkman
    venkman November 11, 2011

    希望php的运行速度更快, 另外就是各个库函数的命名和参数, 返回值要更规范些

  19. pangee
    pangee November 11, 2011

    嗯~ 又出新东西了

Comments are closed.