empty()、is_null()、isset() 是 PHP 判斷變量「空/未定義/為 null」最常用的三個函數,但行為差異極大,誤用極易導致邏輯 Bug。本文通過統一測試用例、底層機制解析、場景化選擇表,徹底釐清三者區別。
統一測試用例與輸出
<?php
$a; // 未定義
$b = false; // 布爾 false
$c = ''; // 空字符串
$d = 0; // 整數 0
$e = null; // null
$f = []; // 空數組
$vars = ['a'=>$a, 'b'=>$b, 'c'=>$c, 'd'=>$d, 'e'=>$e, 'f'=>$f];
echo "=== empty() ===\n";
foreach ($vars as $k=>$v) var_dump($k, empty($v)); // 全 true
echo "\n=== is_null() ===\n";
foreach ($vars as $k=>$v) var_dump($k, is_null($v)); // a:true, b:f, c:f, d:f, e:true, f:f
echo "\n=== isset() ===\n";
foreach ($vars as $k=>$v) var_dump($k, isset($v)); // a:f, b:t, c:t, d:t, e:f, f:t
?>
結果對比表
| 變量值 | empty() | is_null() | isset() | 備註 |
| 未定義 | true | true 1 | false | 1 會觸發 Notice |
| null | true | true | false | |
| false | true | false | true | |
| 0 (int) | true | false | true | |
| '0' (string) | true | false | true | 易踩坑! |
| '' (空串) | true | false | true | |
| [] (空數組) | true | false | true | |
| 'text' | false | false | true | |
| [1,2] | false | false | true | |
核心機制差異
- empty():語言構造,不觸發 Notice。判斷「假值」:
''、0、'0'、null、false、[]、未定義 均為 true。適合業務邏輯「是否為空/無效」。
- isset():語言構造,不觸發 Notice。判斷「變量存在且不為 null」。適合「檢查鍵是否存在/變量已初始化」。
- is_null():函數,參數為變量引用。僅判斷值 === null。未定義變量會觸發 Notice,慎用於未知變量。
場景化選擇指南
| 業務場景 | 推薦函數 | 代碼示例 |
| 判斷用戶提交的字段「是否為空/未填寫」 | empty() | if (empty($_POST['name'])) { 錯誤(); } |
| 判斷配置項/數組鍵「是否已設置(含 false/0/'')」 | isset() | if (isset($config['debug'])) { 用配置值; } else { 用默認值; } |
| 嚴格判斷「值是否為 null」(如區分「未設置」vs「設置為 null」) | is_null() + isset() | if (!isset($v)) { 未設置; } elseif (is_null($v)) { 設置為 null; } else { 有值; } |
| 判斷對象屬性是否存在 | isset() | isset($obj->prop) (觸發 __isset) |
| 判斷數組鍵存在(含 null 值) | array_key_exists() | array_key_exists('k', $arr) (isset 對 null 返回 false) |
高頻踩坑案例
'0' 被 empty 判為 true:分頁參數 page=0、狀態碼 status='0' 會被誤判為「未傳」。
修正:if (!isset($_GET['page']) || $_GET['page'] === '') 或 strlen((string)$val) === 0。
isset($arr['key']) 對 null 值返回 false:需用 array_key_exists('key', $arr) 區分「鍵不存在」vs「鍵存在值為 null」。
is_null($undefinedVar) 觸發 Notice:改用 !isset($var) || is_null($var) 或 $var === null(前提是變量已定義)。
- 對象屬性用 empty():PHP 5.5+ 支持
empty($obj->prop),會調用 __isset(),但邏輯同變量,'0' 仍視為空。
最佳實踐原則
- 優先用
isset() 檢查存在性,無 Notice、語義明確。
- 業務「非空校驗」用
empty(),但明確排除 '0'/0/false 為合法值的字段。
- 極少直接用
is_null(),改用 === null 或配合 isset()。
- 數組鍵檢查用
array_key_exists(),區分 null 值。