在 PHP 面试中,isset()、empty() 和 is_null() 是一组出镜率极高、却极容易被混淆的函数。很多候选人在笔试时能写出它们的定义,但一旦面试官追问“未定义变量传入会怎样”“0 和空字符串算不算空”“为什么 empty() 里不能放函数返回值”,就开始支支吾吾。
这篇文章从面试实战角度出发,把这三个函数的区别、底层行为、常见陷阱和答题思路一次讲清楚。
一、先看定义:三个函数各自在问什么
理解它们的关键,是把每个函数还原成一个“问题”:
isset($var):这个变量存在,并且它的值不是 null,对吗?empty($var):这个变量的值是“假”的,对吗?is_null($var):这个变量的值恰好等于 null,对吗?
注意措辞的差别:isset() 关心的是“存在且非 null”,empty() 关心的是“是否为假值”,is_null() 只关心“是不是 null”。三者判断的维度并不在同一个层面上,这正是混淆的根源。
二、isset 的行为细节
isset() 是语言结构(language construct),不是普通函数,因此它不能通过变量函数的方式调用,也不能接收函数返回值。
它的判断逻辑是:
$var = null;
var_dump(isset($var)); // false
$var = 0;
var_dump(isset($var)); // true
$var = '';
var_dump(isset($var)); // true
var_dump(isset($undefined)); // false,且不报 Notice
关键点有三个:
- 未定义变量返回 false,且不产生警告。这是它和直接读取变量最大的区别,也是它常被用来做“安全探测”的原因。
- 值为 null 时返回 false,哪怕变量确实已经被定义。
- 可以一次传多个参数:
isset($a, $b)等价于isset($a) && isset($b),全部存在且非 null 才返回 true。
三、empty 的行为细节
empty() 同样是语言结构。它的判断标准是:值在布尔上下文中为 false。也就是说,以下这些值都会让 empty() 返回 true:
""(空字符串)0(整数零)0.0(浮点零)"0"(字符串零,这是最容易踩坑的一个)nullfalse[](空数组)- 未定义的变量
var_dump(empty($undefined)); // true,同样不报 Notice
var_dump(empty(0)); // true
var_dump(empty('0')); // true —— 注意!
var_dump(empty('0.0')); // false
var_dump(empty([])); // true
var_dump(empty(new stdClass)); // false,对象永远非空
这里最需要向面试官强调的一点是:empty('0') 返回 true。在表单处理中,用户输入 "0" 是合法值,但用 empty() 判断会被当成“没填”,这是生产环境里的经典 bug。
另外,empty() 只接受一个参数,且不能直接传入函数返回值(PHP 5.5 之前会报错,PHP 5.5+ 支持任意表达式,但传函数调用在部分老版本仍是坑)。面试时如果被问到版本差异,可以补一句:“PHP 5.5 之后 empty() 开始支持任意表达式,之前只能传变量。”
四、is_null 的行为细节
is_null() 是一个真正的函数,因此它可以接收函数返回值、可以嵌套调用,行为也最“单纯”:只有当值严格等于 null 时才返回 true。
var_dump(is_null(null)); // true
var_dump(is_null(0)); // false
var_dump(is_null('')); // false
var_dump(is_null(false)); // false
var_dump(is_null($undefined)); // true,但会产生 Notice
注意最后一行:传入未定义变量时,is_null() 会触发 Undefined variable 警告(因为参数需要先求值),而 isset() 和 empty() 不会。这是三者之间一个非常关键的差异,也是面试官爱问的点。
五、一张表看清全部差异
| 表达式 | isset() |
empty() |
is_null() |
|---|---|---|---|
$x = null |
false | true | true |
$x = '' |
true | true | false |
$x = '0' |
true | true | false |
$x = 0 |
true | true | false |
$x = false |
true | true | false |
$x = [] |
true | true | false |
$x 未定义 |
false | true | true + Notice |
从表中可以总结出一句口诀:isset() 只排除 null,empty() 排除一切假值,is_null() 只认 null。
六、面试常见追问与答题思路
追问 1:判断一个变量“有值”应该用哪个?
如果业务含义是“存在且不为空”,通常用 !empty($var);如果业务含义是“存在即可,哪怕是 0 或空字符串”,则应该用 isset($var)。关键不是哪个函数更好,而是先明确业务对“空”的定义。
追问 2:empty() 和 !isset() 有什么区别?
!isset($x) 在 $x = null 和 $x 未定义时都为 true;而 empty($x) 在 $x = 0、$x = '' 时也为 true。所以 empty() 的范围比 !isset() 大得多。
追问 3:为什么 isset($arr['key']) 比 array_key_exists() 快?
因为 isset() 是语言结构,不涉及函数调用开销,且它对 null 值直接返回 false。如果数组中某个键的值可能是 null,而你仍想判断键是否存在,就必须用 array_key_exists()。
追问 4:empty() 能判断对象属性吗?
可以,empty($obj->prop) 是合法的。但如果 $obj 本身未定义,会报错;此时应先 isset($obj) 或用 empty($obj->prop) 配合对象存在性判断。
七、实战建议
- 表单校验:不要用
empty()判断用户输入,尤其是可能为"0"的字段,改用isset()加显式的长度或类型判断。 - 数组取值:优先
isset($arr['k']),需要区分 null 与不存在时用array_key_exists()。 - 严格比较:在关键逻辑里,用
=== null代替is_null()有时更直观,性能也略好。 - 避免 Notice:任何可能未定义的变量,先用
isset()探测,再读取。
结语
isset()、empty()、is_null() 的区别,本质上不是三个函数的区别,而是三种对“空”和“存在”的定义。面试官问这道题,考的不是记忆力,而是你是否理解 PHP 的弱类型语义,以及是否在真实项目里踩过坑。
回答时如果能主动说出 empty('0') 的陷阱、is_null() 对未定义变量报 Notice 这些细节,基本就能从“背过八股”升级为“真正用过 PHP”。
未经允许不得转载:任鹏个人博客 » PHP 面试题:isset、empty、is_null 到底有什么区别

