核心對照表
| 運算式 | == (鬆散比較) | === (嚴格比較) |
0 == '' | true | false |
0 == null | true | false |
0 == false | true | false |
'' == null | true | false |
'' == false | true | false |
null == false | true | false |
'0' == 0 | true | false |
'0' == false | true | false |
程式碼驗證
<?php
$test = 0;
var_dump($test == ''); // bool(true)
var_dump($test === ''); // bool(false)
var_dump($test == null); // bool(true)
var_dump($test === null); // bool(false)
var_dump($test == false); // bool(true)
var_dump($test === false);// bool(false)
?>
PHP 型別轉換規則 (鬆散比較邏輯)
使用 == 時,PHP 會嘗試將兩側轉換為相同型別再比較:
- 數字 vs 字串 → 字串轉數字 (
"abc" → 0, "123abc" → 123 )
- 布林 vs 任何 → 轉為布林 (
0, "", "0", null, [] → false )
- null vs 字串/數字 → 轉為對應型別
實務陷阱案例
陷阱 1:strpos() 回傳 0 (找到位置) 被誤判為 false
<?php
$str = 'abc';
$pos = strpos($str, 'a'); // 0
if ($pos == false) { // 錯誤!0 == false 為 true
echo "找不到";
} else {
echo "找到位置 $pos";
}
// 正確寫法
if ($pos === false) { /* 找不到 */ }
if ($pos !== false) { /* 找到 */ }
?>
陷阱 2:陣列搜尋 in_array() 預設鬆散比較
<?php
$arr = [0, 1, 2];
var_dump(in_array('foo', $arr)); // true! 'foo' 轉數字為 0
// 正確:啟用嚴格模式
var_dump(in_array('foo', $arr, true)); // false
陷阱 3:switch 使用 === 比較
<?php
$val = '0';
switch ($val) {
case 0:
echo "匹配整數 0"; // 執行! switch 使用鬆散比較 ==
break;
case '0':
echo "匹配字串 '0'";
break;
}
// 輸出:匹配整數 0
?>
陷阱 4:empty() 與 isset() 差異
| 值 | isset() | empty() | 備註 |
0 | true | true | |
'' | true | true | |
'0' | true | true | 字串 "0" 視為空 |
null | false | true | |
false | true | true | |
[] | true | true | |
最佳實踐原則
- 預設使用 === (嚴格比較),除非確定需要型別轉換語意。
- 函數回傳值檢查:
strpos, strstr, array_search 等可能回傳 0 或 false,必須用 === false 判斷失敗。
- 輸入驗證:使用
filter_var(), ctype_*, is_int() 等型別檢查函數,避免鬆散比較驚喜。
- 設定嚴格模式:
declare(strict_types=1); (僅影響標量型別宣告的函數參數/回傳值)。
- 資料庫布林欄位:取出後明確轉型
$active = (bool)$row['active'];。
結語
PHP 鬆散比較 (==) 為了便利性犧牲了嚴謹性,導致 0, '', '0', null, false 互相等價。現代 PHP 開發強烈建議全面採用 ===,僅在極少數明確需要型別轉換語意 (如處理未經過濾的用戶輸入字串比較數字) 時使用 ==。理解型別轉換規則,是寫出健壯 PHP 代碼的分水嶺。
copyright ©
萬盛學電腦網 all rights reserved