笨 猫猫 2010.07.26

Tech-Archive

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(&&)之前不存在了规约冲突. 并且通过规则限制了, T_BOOLEAN_AND的规约结果不能和等号进行规约, 所以就导致了在T_BOOLEAN_AND右边的等号会先一步移进而规约.

另外, 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;

转自http://www.laruence.com/2010/07/26/1668.html

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

可以看成

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

可以任意转载, 转载时请务必以超链接形式标明文章原始出处及此声明

本文地址: http://www.94cat.com/blog/?p=957

1 条评论

  1. 话说php是草根预言
    据说很多都不符合常规运算的

评论

欢迎回来,! ( 更改用户 )

输入后可按 Ctrl+Enter 提交评论.

[bmm1] [bmm2] [bmm3] [bmm4] [bmm5] 更多表情 »
回到页首回到页尾