isset() 判断变量是否存在(非null且已定义),empty() 判断值是否语义为空(如0、""、false、[]等均视为空);二者用途不同,不可混用。

isset() 是“变量在不在”,empty() 是“值算不算空”
这是最本质的区别:一个管存在性,一个管语义空值。比如 $a = 0,isset($a) 返回 true(变量已定义、非 null),但 empty($a) 也返回 true(0 被认为是“空”)。初学者常以为“设了值就一定不空”,结果表单里用户真输入了数字 0,用 empty() 一判,直接当没填——这就是踩坑起点。
-
isset()只拒绝null和未定义变量;0、false、""、[]全部通过 -
empty()把0、"0"、false、null、""、[]、未定义变量,统统当“空” - 对未定义变量:
isset($x)→ false,empty($x)→ true,且都不报 warning -
" "(含空格字符串):isset()为 true,empty()为 false —— 它不是空字符串,只是看着“空”
处理表单数据时,别无脑用 empty()
用户提交 age=0(比如新生儿)、price="0"、active="0",这些是合法业务值,但 empty($_POST['age']) 会误判为“没填”。这时候该用 isset() + 显式类型判断:
if (isset($_POST['age']) && is_numeric($_POST['age'])) {
$age = (int)$_POST['age'];
} else {
// 处理缺失或非法输入
}
- 验证“是否提交了这个字段”→ 用
isset() - 验证“提交的值是否有意义”→ 用
!empty()要谨慎,优先改用strlen(trim($val)) > 0或正则/类型检查 -
"0"字符串是个经典陷阱:empty("0") === true,但它是有效字符串,不能等同于未填写
数组键存在性检查必须用 isset(),不能用 empty()
想确认 $_GET['id'] 是否传了,写 if (!empty($_GET['id'])) 看似省事,但如果 URL 是 ?id=0,逻辑就崩了。正确姿势是:
if (isset($_GET['id']) && $_GET['id'] !== '') {
// id 存在且非空字符串(再按需转 int 或校验格式)
}
-
empty($arr['key'])在键不存在时返回 true,但也会在$arr['key'] = 0时返回 true —— 你根本分不清是“没传”,还是“传了零” -
isset($arr['key'])才能干净区分“键不存在” vs “键存在但值为 null/0/false/''” - PHP 7.4+ 支持空合并操作符:
$id = $_GET['id'] ?? null;,比isset()更简洁,但语义相同(只关心存在性)
5.5+ 的 empty() 支持表达式,但别滥用
新版 PHP 允许 empty($a . $b) 或 empty(foo()),看起来灵活,但实际埋雷:
立即学习“PHP免费学习笔记(深入)”;
- 函数调用可能有副作用(比如修改全局状态、查库),而
empty()的“空”判断本不该触发业务逻辑 - 表达式结果若为
null或false,empty()仍会返回 true —— 可读性差,调试困难 - 绝大多数场景,先赋值再判断更安全:
$val = foo(); if ($val !== '' && $val !== 0) { ... }
真正容易被忽略的点是:这两个函数不是互斥替代品,而是分工明确的工具。用错一个,轻则逻辑错漏,重则绕过权限校验(比如 if (!empty($user->role)) 把 role='guest' 当空跳过)。写之前,先问自己一句:我要确认的是“它有没有”,还是“它有没有用”。











