在学 php,理解不了为什么 $foo->$arr[1] 和 $foo->{$arr}[1] 的结果不一致... - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
gamexg
V2EX  &nbp; PHP

在学 php,理解不了为什么 $foo->$arr[1] 和 $foo->{$arr}[1] 的结果不一致...

  •  
  •   gamexg Mar 24, 2016 4661 views
    This topic created in 3685 days ago, the information mentioned may be changed or developed.
    class foo { var $bar = 'I am bar.'; var $arr = array('I am A.', 'I am B.', 'I am C.'); var $r = 'I am r.'; } $foo = new foo(); $bar = 'bar'; $baz = array('foo', 'bar', 'baz', 'quux'); echo $foo->$bar . "\n"; //$bar 的值是 bar ,$foo->bar 的值是 I am bar echo $foo->$baz[1] . "\n"; //I am bar. $start = 'b'; $end = 'ar'; echo $foo->{$start . $end} . "\n";//$start 的值是'b' ,$end 的值是'ar' ,{$start . $end}的值是 'bar',$foo->{$start . $end} 的值是'I am bar.' $arr = 'arr'; echo $foo->$arr[1] . "\n";// $arr 的值是 'arr' ,$arr[1] 的值是 r $foo->$arr[1]的值是 'I am r.'。 echo $foo->{$arr}[1] . "\n";// 我理解:$arr 的值是 'arr' ,{$arr}[1] 的值是 r $foo->$arr[1]的值是 'I am r.'。但实际输出是 I am B.不太理解这里的运算优先级是什么情况。查手册运算符优先级里面没有 -> ... 

    最后一行实在理解不了为什么输出 I am B ...

    Supplement 1    Mar 25, 2016
    在 php7 两者的结果都变成了"I am B",这种和语言版本相关的特征已经放弃理解了...
    21 replies    2016-03-25 20:24:47 +08:00
    cz208209
        1
    cz208209  
       Mar 24, 2016   1
    php 中的大括号 有一个用法是界定变量的界限,也可以界定表达式{$arr} = 'arr',网上都有总结
    cz208209
        2
    cz208209  
       Mar 24, 2016   1
    还有你这个 类里面用的 var php5*差不多都淘汰了,建议你换高的版本
    wayne712
        3
    wayne712  
       Mar 24, 2016   1
    在 php 中使用 var 声明类成员属性是 php4 时代的写法,
    另外$arr 与{$arr}结果一致没有什么不妥。
    iyaozhen
        4
    iyaozhen  
       Mar 24, 2016   1
    iyaozhen
        5
    iyaozhen nbsp;
       Mar 24, 2016   1
    @iyaozhen
    $$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
    $foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
    $foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
    Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()

    理解就好,而且一般也不这么写,看起来好费劲。
    iyaozhen
        6
    iyaozhen  
       Mar 24, 2016   1
    大括号改变了解释的顺序。
    Sunyanzi
        7
    Sunyanzi  
       Mar 24, 2016   1
    在 $b 等于 c ... $b[$d] 等于 e 的情况下 ...

    在旧版本的 php 中 $a->$b[$d] 的含义是从 a 对象中取得 $c [$d] 的值 ... 即 $e 的值 ...

    使用变量定界符的话 $a->{$b}[$d] 的含义是从 a 对象中优先取得 $c 的值然后取 $d 位 ...

    如楼上所说这种差异在 php7 里面已经不存在了 ... php7 中你这两种情况都视为有定界符 ...

    假如你要获得原始的结果需要使用 $a->{$b[$d]} ... 等同于 $a->e ... 这也是最规范的写法 ...

    两点建议第一是从最新版的 php 用起 ... 现在还从 5.2 年代的教程看起的话未免太过误人子弟 ...

    第二是 php 里面这种小坑其实还挺多的 ... 这类知识点除了面试时候有用实际开发中很难遇到 ...

    所以学的时候觉得头疼也不用太过担心 ... 这不是个常见情况 ... 能记则记不能记也没关系的 ...
    gamexg
        8
    gamexg  
    OP
       Mar 24, 2016
    这个是直接复制的 php.net 的例子,就没动 var 声明。

    @wayne712 问题是结果不一致...
    @laucie 搜索了 Php 中"{}"大括号的用法总结,但是还是不理解这里的运算优先级。

    $foo->$arr[1] 是[]运算符优先,但是 $foo->{$arr}[1] 就变成了 -> 运算符优先。怎么理解 -> [] 的优先级呢?
    查 php 文档运算符优先表里面没有->,好头疼...


    @iyaozhen 的确在 php7 下结果变了,这样会让一些程序掉坑里吧?

    echo $foo->$arr[1]
    echo $foo->{$arr}[1]
    都输出 "I am B."
    gamexg
        9
    gamexg  
    OP
       Mar 24, 2016
    @Sunyanzi 的确,实际应用中基本用不到,这种复杂的情况一般都会手动指定优先级。

    看的是 php.net 的中文文档,刚刚又看了一下英文版本,发现删掉了这一部分,并说明 php7 有变更,详情查看 php7 迁移指南。
    不过英文版本也很多地方没更新,这里还是使用 var 声明的类变量。
    cxbig
        10
    cxbig  
       Mar 24, 2016
    输出 B 是因为 Array 的 index 从 0 开始, 1 当然是输出第二个。
    jhdxr
        11
    jhdxr  
       Mar 24, 2016   1
    @gamexg 手册更新也是逐步的。。。能否告知下你看的是中文手册的那一部分,我去更新下_(:з」∠)_
    MrZephyrus
        12
    MrZephyrus  
       Mar 25, 2016 via iPhone
    @cxbig 233 你理解错楼主意思了
    gamexg
        13
    gamexg  
    OP
       Mar 25, 2016
    likezun
        14
    likezun  
       Mar 25, 2016
    为什么要简单的问题,搞这么复杂! 我觉得编程就应避繁从简,回避这种容易产生歧义用法
    cxbig
        15
    cxbig  
       Mar 25, 2016
    @MrZephyrus 好像是的,他的问题不在 index ,在 variable 名称变换

    @gamexg 话说你这个例子看看就好,实际开发都是不规范的写法,不必太深究这种变换
    bombless
        16
    bombless  
       Mar 25, 2016 via Android
    php 里面不是传统的解析 ast 的那种思路, 233 。它的语法设计思路在某种意义上跟 Ruby 的语意设计思路有点像
    luffyfly
        17
    luffyfly  
       Mar 25, 2016
    理解这个完全是浪费时间,我写了五六年 php ,也理解不了。。。
    wudanyang
        18
    wudanyang  
       Mar 25, 2016
    这个是链式结构,我问过这个问题,楼主看一下这个->https://segmentfault.com/q/1010000004486442
    jhdxr
        19
    jhdxr  
       Mar 25, 2016
    @bombless PHP7 开始也引入 AST 了
    leitwolf
        20
    leitwolf  
       Mar 25, 2016
    怎么感觉是要去考试一样?计算机语言用的时候都是挑一种简单好理解就行了,考试才会找出各种对的和错误的。。。
    gamexg
        21
    gamexg  
    OP
       Mar 25, 2016
    @leitwolf 打算认真学习下 php ,看 php.net 文档时碰到了这个问题,实在太违反常识了...
    About     Help     Advertise     Blog     API     FAQ     Solana     4039 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 65ms UTC 04:15 PVG 12:15 LAX 21:15 JFK 00:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86