isset()判断变量是否已声明且不为null,对0、"0"、false、""等均返回true;empty()语义化判空,将0、"0"、null、false、""、[]等视为“空”并返回true,但无法区分“未定义”和“值为零”。

isset()只管“有没有”,不care值是不是0或空字符串
判断一个变量是否被声明、且不是null,就该用isset()。它对0、"0"、false、""、[]全部返回true——只要变量存在且没被设成null,它就点头放行。
常见错误现象:if (!empty($_GET['id'])) { ... } 遇到 URL 是 ?id=0 时直接跳过,但 ID 为 0 完全合法(比如默认分类、根节点)。
- 正确姿势:
if (isset($_GET['id']) && is_numeric($_GET['id'])) { ... } - PHP 7.4+ 更推荐:
$id = $_GET['id'] ?? null;,再单独校验类型或范围 - 访问数组键前必须先
isset($arr['key']),否则可能触发 notice 或 fatal error(尤其在严格模式下)
empty()是语义级“空判断”,0和"0"都算空,但你业务里可能不这么认为
empty()不是“非空检测”,而是把一堆看起来“没意义”的值打包判空:未定义变量、null、false、0、"0"、""、[]……全返回true。它不区分“根本没传”和“传了但值是零”。
典型踩坑:$price = 0; 表示免费商品,!empty($price) 却为false,导致价格被过滤掉;$age = 0;(新生儿),empty($age) 也返回true,误判为“未填写”。
立即学习“PHP免费学习笔记(深入)”;
- 表单必填字段验证慎用
empty(),优先组合:isset($val) && trim($val) !== '' - 若需兼容数字 0,改用
is_string($val) ? trim($val) !== '' : $val !== 0这类显式逻辑 -
empty()不能用于表达式,如empty($a + $b)会报错——它只接受变量
数组键存在性必须用isset(),empty()会混淆“没这个键”和“有键但值为0”
检查$arr['name']是否存在,只能靠isset($arr['name'])。因为empty($arr['name'])在两种完全不同的情况下都返回true:
- 键
'name'根本不存在(undefined index) - 键存在,但值恰好是
0、false或null
你无法从empty()结果反推出状态,而isset()能明确告诉你:“这个键有没有被设置”。
另外注意:$str = " ";(含空格)时,isset($str)为true,empty($str)也为false,但它业务上往往该当“空”处理——这时候必须手动加trim(),别指望任一函数自动搞定。
isset是语言结构,empty是函数,这点影响动态调用和性能
isset()是 PHP 内置语言结构,执行快、不能当变量函数调用;empty()是普通函数,支持动态执行但几乎没实用价值。
-
$func = 'isset'; $func($var);→ 直接报错:Fatal error: Call to undefined function isset() -
$func = 'empty'; $func($var);→ 合法但掩盖意图,增加维护成本 - 真实项目中,二者都应直写,不包装、不代理、不抽象——清晰比“灵活”重要得多
最常被忽略的一点:空格字符串" "是isset()为true、empty()也为false的特例。它既“存在”,又“不空”,但业务上往往要当“空”处理。这时候就得自己加trim(),别指望任一函数自动搞定。



















