empty() 在 PHP 5.5+ 仅支持数组下标、对象属性、字符串偏移及多维嵌套访问等变量式表达式,不支持函数调用、算术运算或 isset() 等复杂表达式,且对缺失键或类型不符情况静默返回 true。

empty() 在 PHP 5.5 及之后版本可以判断表达式,但有严格限制:它只接受「可求值的表达式」,且不能是任意函数调用或复杂语句。
empty() 支持哪些表达式?
PHP 5.5+ 将 empty() 从纯变量检查器升级为支持部分表达式,但仅限于以下几类:
- 数组下标访问:如
empty($arr['key'])、empty($arr[0]) - 对象属性访问(含箭头语法):如
empty($obj->prop)、empty($obj?->prop) - 字符串偏移:如
empty($str[0])、empty($str['offset'])(注意:非数字字符串偏移会静默转为0或引发 notice) - 多维嵌套访问:如
empty($data['user']['profile']['name'])
不支持的典型例子:
-
empty(trim($str))→ 解析错误(PHP 5.5+ 仍不支持函数调用作为参数) -
empty($a + $b)→ 解析错误 -
empty(isset($x))→ 解析错误 -
empty($arr['key'] ?? '')→ PHP 7.0+ 允许,但本质是语言层面对空合并操作符的支持,不是empty()自身解析表达式
为什么 empty(trim($str)) 会报错?
这是最常踩的坑。错误信息通常是:
立即学习“PHP免费学习笔记(深入)”;
Parse error: syntax error, unexpected 'trim' (T_STRING)
因为 empty() 是语言结构(language construct),不是普通函数,其参数在解析期就被特殊处理。PHP 5.5+ 扩展的是「变量式表达式」的语法支持,而非通用表达式求值。
替代写法必须拆开:
$trimmed = trim($str);
if (empty($trimmed)) { /* ... */ }或者更直接地:
if (trim($str) === '') { /* ... */ }后者更准确——因为业务上你往往关心“是否只有空白”,而不是“是否 falsy”。
多维数组里用 empty() 容易误判什么?
empty($arr['a']['b']['c']) 看似安全,但存在两个隐性风险:
- 如果
$arr['a']不存在,PHP 不报错(empty()的设计特性),直接返回true - 如果
$arr['a']存在但不是数组(比如是字符串'hello'),那么$arr['a']['b']实际触发字符串偏移行为:'hello'[0]是'h',而'hello'['b']等价于'hello'[0](因'b'强转为 int 是 0),结果不可控
所以,当结构不确定时,别依赖嵌套 empty() 做深层校验;应先用 isset() 或 array_key_exists() 显式确认路径存在。
真正容易被忽略的是:empty() 的“宽松”和“静默”是一体两面。它省去了 isset() + == false 的组合判断,但也因此掩盖了类型混淆(比如 "0" 和 0 都被当空)和结构误读(比如字符串当数组用)。业务关键字段校验,往往需要比 empty() 更明确的逻辑。



















