msgbartop
PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 – 左手代码 右手诗
msgbarbottom

26 Jul 10 PHP运算符优先级的一个例外

今天在老王的技术手册看到一个问题:

<?php
if ($a = 100 && $b = 200) {
	var_dump($a, $b);
}

输出是什么?

这个问题, 咋一看或许觉得简单, 但其实仔细推敲并不简单,

如果说布尔与之前的部分, 是由于优先级的问题, 但是如果仅仅是优先级的问题的话, 那么结果应该是:

$a = (100 && $b) = 200

而实际上的结果, 确实高优先级的&&让步给次优先级的=, 让 $b = 200 先结合了.

究其原因, 是因为PHP并不完全遵守优先级的定义, 这个在PHP的手册中也有说明:

Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.

这样的设计, 个人不发表看法, 反正在C语言中, 这样类似的语句是判定为语法错的. PHP采用这样的设计, 很可能是历史原因,

有好奇的同学, 会想知道到底为什么, 之前jayeeliu网友也问过:

laruence你好:
问一个php运算符优先级的问题
$t == 1 && $tt = 2
按照php运算符优先级应该是
(($t == 1) && $tt) = 2
这个顺序执行,但实际上应该是
($t == 1) && ($tt = 2)
我有些不太理解。

其实也简单, 运算符优先级是在存在二义性文法的时候的一种规约规则选择的手段, 而PHP的语法分析文件定义中, 却让等号和T_BOOLEAN_AND(&&)之前不存在了规约冲突:

expr_without_variable:
  // 有隐规则存在, 相当于T_BOOLEAN_AND成为了"一元操作符".
  |   expr T_BOOLEAN_AND  { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } expr

最后, 顺便说一下, PHP对应于T_BOOLEAN_AND 还定义了 T_LOGICAL_AND(and) 和 T_LOGICAL_OR(or) , 这俩个的优先级都低于等号, 于是就会有了, 很多PHP入门教材示例代码中经典的:

$result = mysql_query(*)  or die(mysql_error());

类似的还可以用or来实现三元操作符(?:)的功能:

	$person = $who or $person = "laruence";
//等同于:
	$person = empty($who)? "laruence" : $who;


分享到:



Related Posts:

Tags: , ,

28 Responses to “PHP运算符优先级的一个例外”

  1. mace |

    @DDDDemo
    个人感觉你这段

    !$a=false && $b=100

    实际执行效果应该是

    !($a = (false && ($b = 100)))

  2. nangua |

    最后一个例子有些问题。对于who未定义的情况,这样会被发出警告信息的。
    Notice: Undefined variable: who 。而用empty则不会

  3. DDDDemo |

    大神您好,我现在有一个问题不太理解。
    if($a=true && $b=100){
    var_dump($a,$b);
    }
    我把代码改成上面这样,仍然是预期的结果
    但是我改成下面这样的时候
    if(!$a=false && $b=100){
    var_dump($a,$b);
    }

    不仅notice,$b也是null。
    是否我遗漏了什么知识点呢?

  4. cctwl |

    $a = 1;
    $a = $a + $a + ($a = 2) ; //结果是4
    $a = $a + ($a = 2) ; //结果是4

  5. 风雪之隅-鸟哥文章汇总 | 互联网菜鸟 |

    [...] Jul 10 PHP运算符优先级的一个例外  30 Jul 10 注意PHP对字符串的递增运算 18 Aug 10 将PHP [...]

  6. xonze |

    $a = 1;
    $b = &$a;
    echo ++$a + $a++;
    //鸟哥,这里因为上一句$b = &$a;导致结果是5不是4,这是为什么?

  7. 秋风 |

    受益匪浅,学习了!

  8. 胡小光 |

    php 手册上是有说明 php 运算符的优先级的,http://www.php.net/manual/zh/language.operators.precedence.php,哥不要在这里诱导人家好不

  9. bird |

    @azhun 而且,在js里 = 的优先级比 logical operator 低

  10. 雪候鸟 |

    @azhun 这个还不太一样, js的||返回的是变量本身, 而PHP的逻辑运算返回的是boolean

  11. azhun |

    Javascript也类似于此,例如 var e = a || b;

  12. PHP运算符优先级的一个例外 | 万维网黑客联盟 |

    [...] 本文地址: http://www.laruence.com/2010/07/26/1668.html [...]

  13. iterse |

    看来以后还要多看看细节。

  14. toobull.com |

    不错…以前都没刻意注意过..

  15. Bun Wong |

    恩,恩,确实是这样的

  16. Audio |

    以前还一直没遇到过这种情况,受教了!以后写代码还是要多按标准写!

  17. 蓝色夏威夷 |

    额,有意思啊。

  18. Think In LAMP Blog » Blog Archive » PHP每周通讯(20100802) |

    [...] 风雪之隅       PHP运算符优先级的一个例外             http://www.laruence.com/2010/07/26/1668.html  [...]

  19. 排头兵 |

    受教,呵呵。

    优先级 !!!

  20. 網站製作學習誌 » [Web] 連結分享 |

    [...] PHP运算符优先级的一个例外 [...]

  21. PHP运算符的两个问题 | yeeger.com |

    [...] 本文地址: http://www.laruence.com/2010/07/26/1668.html [...]

  22. 雪候鸟 |

    @anyharding 我们可以要求自己的代码易读, 但无法保证别人的代码. :)

  23. 火跃 |

    不错!学习了!

  24. anyharding |

    为什么要写歧义代码,加上小括号不就好了吗?
    代码是让人读的,提高可读性的同时,也避免犯一些错误

  25. 雪候鸟 |

    @yyj 你想xss我? 太坏了..

  26. yyj |

    alert(‘ddd’);

  27. liruqi |

    这种问题挺tricky
    还是尽量避免magic code比较方便。

  28. 半醒 |

    mysql connect那语句的确很经典

    这种优先级的约束能不能认为是更符合人的自然思维?

Leave a Reply

*