比較運(yùn)算符,如同它們名稱所暗示的,允許對兩個值進(jìn)行比較。還可以參考 PHP 類型比較表看不同類型相互比較的例子。
例子 | 名稱 | 結(jié)果 |
---|---|---|
$a == $b | 等于 | true ,如果類型轉(zhuǎn)換后 $a 等于 $b。 |
$a === $b | 全等 | true ,如果 $a 等于 $b,并且它們的類型也相同。 |
$a != $b | 不等 | true ,如果類型轉(zhuǎn)換后 $a 不等于 $b。 |
$a <> $b | 不等 | true ,如果類型轉(zhuǎn)換后 $a 不等于 $b。 |
$a !== $b | 不全等 | true ,如果 $a 不等于 $b,或者它們的類型不同。 |
$a < $b | 小與 | true ,如果 $a 嚴(yán)格小于 $b。 |
$a > $b | 大于 | true ,如果 $a 嚴(yán)格大于 $b。 |
$a <= $b | 小于等于 | true ,如果 $a 小于或者等于 $b。 |
$a >= $b | 大于等于 | true ,如果 $a 大于或者等于 $b。 |
$a <=> $b | 太空船運(yùn)算符(組合比較符) | 當(dāng)$a小于、等于、大于 $b時 分別返回一個小于、等于、大于0的 int 值。 |
當(dāng)兩個操作對象都是
數(shù)字字符串,
或一個是數(shù)字另一個是
數(shù)字字符串,
就會自動按照數(shù)值進(jìn)行比較。
此規(guī)則也適用于
switch 語句。
當(dāng)比較時用的是 ===
或 !==
,
則不會進(jìn)行類型轉(zhuǎn)換——因為不僅要對比數(shù)值,還要對比類型。
PHP 8.0.0 之前,如果 string 與數(shù)字或者數(shù)字字符串進(jìn)行比較, 則在比較前會將 string 轉(zhuǎn)化為數(shù)字。 在如下示例中會出現(xiàn)不可預(yù)料的結(jié)果:
<?php
var_dump(0 == "a");
var_dump("1" == "01");
var_dump("10" == "1e1");
var_dump(100 == "1e2");
switch ("a") {
case 0:
echo "0";
break;
case "a":
echo "a";
break;
}
?>
以上例程在 PHP 7 中的輸出:
bool(true) bool(true) bool(true) bool(true) 0
以上例程在 PHP 8 中的輸出:
bool(false) bool(true) bool(true) bool(true) a
<?php
// 整數(shù)
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮點數(shù)
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1
// 數(shù)組
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
// 對象
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 0
$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b; // -1
$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 1
// 不僅僅比較值,而且也會匹配鍵
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b; // 1
?>
對于多種類型,比較運(yùn)算符根據(jù)下表比較(按順序)。
運(yùn)算數(shù) 1 類型 | 運(yùn)算數(shù) 2 類型 | 結(jié)果 |
---|---|---|
null 或 string | string | 將 null 轉(zhuǎn)換為 "",進(jìn)行數(shù)字或詞匯比較 |
bool 或 null | 任何其它類型 | 轉(zhuǎn)換為 bool,false < true |
object | object | 內(nèi)置類可以定義自己的比較,不同類不能比較,相同類和數(shù)組同樣方式比較屬性(PHP 4 中),PHP 5 有其自己的說明 |
string、resource、int、float | string、resource、int、float | 將字符串和資源轉(zhuǎn)換成數(shù)字,按普通數(shù)學(xué)比較 |
array | array | 具有較少成員的數(shù)組較小,如果運(yùn)算數(shù) 1 中的鍵不存在于運(yùn)算數(shù) 2 中則數(shù)組無法比較,否則挨個值比較(見下例) |
object | 任何其它類型 | object 總是更大 |
array | 任何其它類型 | array 總是更大 |
示例 #1 Boolean/null comparison
<?php
// Bool 和 null 總是作為 bool 比較
var_dump(1 == TRUE); // TRUE - same as (bool)1 == TRUE
var_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSE
var_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUE
var_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 is FALSE < TRUE
?>
示例 #2 標(biāo)準(zhǔn)數(shù)組比較代碼
<?php
// 數(shù)組是用標(biāo)準(zhǔn)比較運(yùn)算符這樣比較的
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
?>
由于浮點數(shù) float 的內(nèi)部表達(dá)方式,不應(yīng)比較兩個浮點數(shù)float是否相等。
更多信息參見 float。
另一個條件運(yùn)算符是“?:”(或三元)運(yùn)算符 。
示例 #3 賦默認(rèn)值
<?php
// 三元運(yùn)算符的例子
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// 以上等同于以下的 if/else 語句
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
(expr1) ? (expr2) : (expr3)
在
expr1 求值為 true
時的值為 expr2,在
expr1 求值為 false
時的值為
expr3。
可以省略三元運(yùn)算符中間那部分。表達(dá)式
expr1 ?: expr3
在
expr1 求值為 true
時返回
expr1,否則返回
expr3。
注意: 注意三元運(yùn)算符是個語句,因此其求值不是變量,而是語句的結(jié)果。如果想通過引用返回一個變量這點就很重要。在一個通過引用返回的函數(shù)中語句
return $var == 42 ? $a : $b;
將不起作用,以后的 PHP 版本會為此發(fā)出一條警告。
注意:
建議避免將三元運(yùn)算符堆積在一起使用。和其他語言相比, 當(dāng)在單個表達(dá)式中使用多個未加括號的三元運(yùn)算符時會造成 PHP 運(yùn)算結(jié)果不清晰。 甚至在 PHP 8.0.0 之前,三元運(yùn)算符是從左到右執(zhí)行的, 而大多數(shù)其他編程語言是從右到左的。 自 PHP 7.4.0 起,棄用依靠左聯(lián)。 PHP 8.0.0 起,三元運(yùn)算符是非關(guān)聯(lián)的。
示例 #4 不清晰的三元運(yùn)算符行為
<?php
// 乍看起來下面的輸出是 'true'
echo (true ? 'true' : false ? 't' : 'f');
// 然而,上面語句的實際輸出是't',因為在 PHP 8.0.0 之前三元運(yùn)算符是左聯(lián)的
// 下面是與上面等價的語句,但更清晰
echo ((true ? 'true' : 'false') ? 't' : 'f');
// 這里可以看到第一個表達(dá)式的計算結(jié)果是 “true”,第二個表達(dá)式的計算結(jié)果為 (bool)true,
// 因此返回第二個三元表達(dá)式的 true 分支。
?>
而且存在 "??" (NULL 合并)運(yùn)算符。
示例 #5 設(shè)置默認(rèn)值
<?php
// NULL 合并運(yùn)算符的例子
$action = $_POST['action'] ?? 'default';
// 以上例子等同于于以下 if/else 語句
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>
null
,表達(dá)式 (expr1) ?? (expr2)
等同于
expr2,否則為 expr1。
尤其要注意,當(dāng)不存在左側(cè)的值時,此運(yùn)算符也和 isset() 一樣不會產(chǎn)生警告。 對于 array 鍵尤其有用。
注意: 請注意:NULL 合并運(yùn)算符是一個表達(dá)式,產(chǎn)生的也是表達(dá)式結(jié)果,而不是變量。 返回引用變量時需要強(qiáng)調(diào)這一點。 因此,在返回引用的函數(shù)里就無法使用這樣的語句:
return $foo ?? $bar;
,還會提示警告。
注意:
請注意,NULL 合并運(yùn)算符支持簡單的嵌套:
示例 #6 嵌套 NULL 合并運(yùn)算符
<?php
$foo = null;
$bar = null;
$baz = 1;
$qux = 2;
echo $foo ?? $bar ?? $baz ?? $qux; // 輸出 1
?>