核心差異速查表
| 變量值 | empty() | is_null() | isset() |
| $a = "" | true | false | true |
| $a = null | true | true | false |
| var $a; (未初始化) | true | true | false |
| $a = [] | true | false | true |
| $a = false | true | false | true |
| $a = 15 | false | false | true |
| $a = 1 | false | false | true |
| $a = 0 | true | false | true |
| $a = "0" | true | false | true |
| $a = "true" | false | false | true |
| $a = "false" | false | false | true |
函數語義深度解析
isset() - 變量是否「存在且非 null」
- 檢查變量是否聲明並賦值非 null
- 可檢查多個:`isset($a, $b, $c)` 全真才返回 true
- 支援鏈式:`isset($obj->prop)`, `isset($arr['key'])`
- **不會觸發「未定義變量」警告**
empty() - 變量是否為「空值」
- 等價於 `!isset($var) || !$var` (PHP 5.5+ 支援表達式)
- 「空值」包括:`""`, `0`, `"0"`, `null`, `false`, `[]`, 未聲明變量
- **不會觸發警告**
- 常用於表單驗證:`if (empty($_POST['name']))`
is_null() - 變量是否「嚴格等於 null」
- 僅 `null` 返回 true
- 變量未聲明會觸發 Notice 警告
- 嚴格類型檢查:`is_null($x) === ($x === null)`
實戰選擇指南
| 場景 | 推薦函數 | 代碼示例 |
| 檢查用戶是否提交了字段 | isset() | `if (isset($_POST['submit']))` |
| 驗證必填字段非空 | empty() | `if (empty($_POST['username']))` |
| 區分「未提交」vs「提交空值」 | isset() + empty() | `isset($_GET['q']) && !empty($_GET['q'])` |
| 檢查配置項是否明確設置為 null | is_null() | `if (is_null($config['cache_ttl']))` |
| 數組鍵存在性 | array_key_exists() | `array_key_exists('key', $arr)` (區分 null 值) |
常見坑點
// 1. 魔術方法影響
class Test {
public function __isset($name) { return true; }
public function __get($name) { return null; }
}
$t = new Test();
isset($t->foo); // true (調用 __isset)
empty($t->foo); // true (__get 返回 null)
is_null($t->foo); // true
// 2. 0 和 "0" 的業務陷阱
$score = $_POST['score'] ?? 0; // 用戶輸入 0 分
if (empty($score)) { /* 錯誤:視為未填寫 */ }
if (!isset($score)) { /* 正確:但 $_POST 總是 set */ }
if ($score === '' || $score === null) { /* 業務正確判斷 */ }
// 3. 嚴格類型聲明下的差異
declare(strict_types=1);
function foo($x = null) {
var_dump(isset($x), empty($x), is_null($x));
}
foo(); // true, true, true
foo(null); // true, true, true
foo(0); // true, true, false
總結口訣
- isset:有值且非 null(查字典)
- empty:假值大全(查戶口)
- is_null:純粹是 null(查身份證)
記住:`isset`/`empty` 是語言構造器(不觸發警告),`is_null` 是普通函數。業務邏輯中,**優先用嚴格比較 (`===`, `!==`) 替代這三個函數**,語義更清晰、行為更可預期。