1. 程式人生 > >PHP運算子優先順序的一個例外

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;