這三個函數是 PHP 變量狀態判斷的核心工具,但行為差異極大。本文通過真值表、底層語義分析、實戰場景映射,建立清晰的決策模型。
核心語義速查
| 函數 | 判斷目標 | 返回 true 條件 | 參數要求 |
isset() | 變量是否「存在且非 null」 | 已定義 且 ≠ null | 只能是變量(可多個參數,全 true 才返回 true) |
empty() | 值是否為「假值」 | == false(0, '', '0', null, false, [], 未定義) | 只能是變量(PHP 5.5+ 支援表達式) |
is_null() | 值是否「嚴格為 null」 | === null | 任意表達式(未定義變量會 Warning) |
完整真值表
| 變量狀態 | 值 | isset() | empty() | is_null() | (bool) |
| 未定義 | - | false | true | Warning+true | false |
| 定義未賦值 | - | false | true | Warning+true | false |
| 賦值 null | null | false | true | true | false |
| 賦值 false | false | true | true | false | false |
| 賦值 0 | 0 | true | true | false | false |
| 賦值 '0' | '0' | true | true | false | false |
| 賦值 '' | '' | true | true | false | false |
| 賦值 [] | [] | true | true | false | false |
| 賦值 1 | 1 | true | false | false | true |
| 賦值 'hello' | 'hello' | true | false | false | true |
| 賦值 [1] | [1] | true | false | false | true |
| 賦值 new StdClass() | object | true | false | false | true |
關鍵推論規律
empty($var) === !(bool)$var (不報錯版);
is_null($var) === !$var === null 但 is_null 會對未定義變量報 Warning;
isset($var) === !is_null($var) 當變量已定義時;
isset($var) && !empty($var) ⇔ 變量存在且為真值(非 0、非空、非 false、非 null)。
實戰決策樹:我該用哪個?
// 1. 判斷配置項是否「用戶顯式設置」(區分 null 和未設置)
if (isset($config['key'])) { ... } // 用戶可能設置為 null 也視為已設置
// 2. 判斷輸入是否「有實際內容」(拒絕 0、'0'、false、空陣列)
if (!empty($input)) { ... } // 最常用:表單驗證、API 參數檢查
// 3. 判斷變量是否「確切為 null」(如緩存未命中標記)
if ($cache->get($key) === null) { ... } // 推薦用 === null,不報錯
// 或
if (is_null($cache->get($key))) { ... } // 確定變量已定義時可用
// 4. 判斷陣列鍵是否存在(不關心值)
if (array_key_exists('key', $arr)) { ... } // 包含 null 值
if (isset($arr['key'])) { ... } // 排除 null 值
// 5. 多變量同時檢查
if (isset($a, $b, $c)) { ... } // 全部存在且非 null
if (empty($a) || empty($b)) { ... } // 任一為空
高頻避坑指南
| 錯誤代碼 | 問題 | 修正 |
empty($obj->prop) | PHP 5.5+ 支援,但魔術 __get 可能觸發副作用 | 先 isset($obj->prop) 再取值 |
is_null($undefined) | 觸發 Warning 污染日誌 | 用 === null 或 isset() 反向 |
isset($arr['key']) 判斷鍵存在 | 值為 null 返回 false | 用 array_key_exists() |
empty($var) 當 $var='0' | 業務上 '0' 可能是有效值(如狀態碼) | 顯式 $var === '' || $var === null ... |
isset($var) 用於屬性/數組元素 | 魔術方法/偏移不存在不報錯但返回 false | 屬性用 property_exists(),陣列用 array_key_exists() |
性能微優化
isset()、empty() 是語言構造,非函數調用,極快;
is_null() 是函數,有微小開銷,熱路徑用 === null;
- 批量檢查用
isset($a, $b, $c) 單次調用。
建立「語義 → 函數」的肌肉記憶,比背誦真值表更可靠。