PHP 的類型轉換規則導致 0 == ''、0 == null、0 == false 皆為 true,而 === 則區分類型。本文從 Zend 引擎結構體角度解析底層機制,並給出實戰比較策略表。
PHP 變量在 C 層用 zval 結構體表示(簡化版):
struct _zval_struct {
zend_value value; // 聯合體:存儲實際值
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar type, // 類型標籤:IS_LONG, IS_STRING, IS_NULL, IS_FALSE...
zend_uchar type_flags,
zend_uchar const_flags,
zend_uchar reserved
)
} v;
uint32_t type_info;
} u1;
// ... 引用計數等
};
關鍵點:
value 聯合體中,0、'' (空字串)、null、false 的數值部分皆為 0;type_info 標識真實類型:IS_LONG(0)、IS_STRING('')、IS_NULL、IS_FALSE;== 僅比較 value 數值部分(經過類型轉換);=== 同時比較 value 與 type_info。| 表達式 | == 結果 | === 結果 | 說明 |
|---|---|---|---|
0 == '' | true | false | 字串轉長整型為 0 |
0 == '0' | true | false | 字串 '0' 轉長整型為 0 |
0 == null | true | false | null 轉長整型為 0 |
0 == false | true | false | false 轉長整型為 0 |
'' == null | true | false | 均轉為 0/空 |
'' == false | true | false | 同上 |
null == false | true | false | 同上 |
'0' == false | true | false | 字串 '0' 被視為假值 |
[] == '' | false | false | 陣列不能轉字串比較 |
[] == null | false | false | 同上 |
| 值 | empty() | isset() | is_null() | (bool) |
|---|---|---|---|---|
| 0 | true | true | false | false |
| '0' | true | true | false | false |
| '' | true | true | false | false |
| null | true | false | true | false |
| false | true | true | false | false |
| [] | true | true | false | false |
| 未定義變量 | true | false | 報錯 | false |
empty():判斷「假值」,等價於 ! (bool)$var 但不報錯;isset():判斷變量存在且非 null;is_null():僅判斷值為 null,傳入未定義變量會觸發 Warning;(bool)$var:強制轉布林,規則與 empty() 相反。=== 和 !==,除非確定需要類型轉換語義;isset($var) 或 array_key_exists('key', $arr);$var === null(不報錯)優於 is_null($var);// 寫法 1:明確語義
if ($var !== null && $var !== '' && $var !== false && $var !== 0 && $var !== '0') { ... }
// 寫法 2:封裝函數
function is_filled($val): bool {
return $val !== null && $val !== '' && $val !== false && $val !== 0 && $val !== '0';
}
// 寫法 3:利用 empty() 反義(注意 '0' 會被視為空)
if (!empty($val) || $val === '0') { ... } // 視業務決定是否接受 '0'
INT 欄位讀出為 string 類型的數字(如 '0'),用 === 比較會失敗;ATTR_STRINGIFY_FETCHES => false (PHP 8.1+) 或 ATTR_EMULATE_PREPARES => false 保持原生類型;$id = (int)$row['id']。理解 PHP 比較的底層機制,能從根源消除「為什麼 0 等於空字串」這類困惑,寫出可預測的邏輯判斷。