如果变量不存在,或者它的值是假值(null、false、0、0.0、""、"0" 或空数组 []),empty($var) 返回 true,其他任何值都返回 false。和 isset() 一样,它从不对未定义的变量或数组键发出警告。
empty($x) 等同于 !isset($x) || !$x。也就是说:不存在,或者会转换成 false。
哪些值算空
在表格中选一个值,就能看到 empty() 与 isset() 以及 (bool) 强制转换的结果对比。每个单元格都由 PHP 8.3 计算得出。
| $x | empty | isset | bool |
|---|---|---|---|
| null | |||
| false | |||
| 0 | |||
| 0.0 | |||
| "" | |||
| "0" | |||
| [] | |||
| " " | |||
| "0.0" | |||
| "a" | |||
| "null" | |||
| [0] | |||
| 1 | |||
| -1 |
意外出现在两头:"0" 是空的,而 " "(一个空格)、"0.0"、"null" 和 [0] 都不是。
"0" 是空的:一个经典 bug
因为 "0" 是假值,empty() 会把数量为 0、分数为 0 或 PIN 为 "0" 都当成“没有填写”。这在表单中特别容易出问题,因为表单里的每个值都是字符串。
对于文本输入,判断“没有填写”的可靠方法是 trim($value) === ""。empty() 只留给 0 确实表示“没有”的值。
判断字符串是否为空
要精确判断空字符串,就和 "" 比较。如果空白也算空,先用 trim 处理。从 PHP 5.5 起 empty() 可以接受表达式,所以 empty(trim($s)) 也能用(但同样有 "0" 的问题)。
在 PHP 8.1 及以后版本中,把 null 传给 trim() 会产生弃用提示,所以上面的代码写成了 trim($s ?? "")。
判断数组是否为空
对数组来说,empty($arr)、$arr === [] 和 count($arr) === 0 给出的结果相同。empty() 的好处是可以用在可能不存在的变量或键上。
不带回调的 array_filter() 会移除所有假值,所以它是判断“这个数组里有没有实际内容”的快捷方法。
校验必填表单字段
只要 0 不是有效答案,!empty() 就是要求字段必填的常用写法。运行这段代码,先让字段留空并点击 Send,再填好后重新发送:脚本会带着填好的 $_POST 再运行一次。
对复选框来说,empty($_POST["terms"]) 同时覆盖了两种情况:完全没有提交,或者提交了空值。表单页面更进一步,介绍了按字段显示的错误信息。
empty 与 isset 的区别
两者对未定义的变量和键都是安全的,但它们回答的问题不同:
isset($x):它是否存在且不为null?用于可选键、复选框,以及“到底有没有提交”。!empty($x):它是否存在且为真值?用于“有实际内容”的判断,此时0和"0"不算数。$x === ""或$x === []:它是否恰好为空?0是有效值时用这种写法。
isset 页面介绍了另一半内容,包括用 isset() 一次检查多个变量,以及它与 array_key_exists() 的区别。
常见问题
PHP 的 empty() 认为哪些值是空的?
当 $x 不存在,或者是 null、false、0、0.0、""、"0"、[] 时,empty($x) 为 true。其他值都不算空,包括 " "(一个空格)、"0.0"、"false" 和 [0]。
为什么 PHP 中 "0" 是空的?
empty() 等同于不会对未定义变量发出警告的 !$x,而字符串 "0" 会转换成 false。所以对 0 是有效答案的字段,empty() 并不适用;应改用 $x === '' 或 trim($x) === '' 判断。
PHP 中怎么判断数组是否为空?
empty($arr) 和 $arr === [] 都可以,count($arr) === 0 也行。empty() 在变量未设置时同样返回 true,而对未定义的变量调用 count() 会先发出警告,再因为 null 抛出 TypeError。
什么时候用 empty() 而不用 isset()?
只需要知道值是否存在时(复选框是否提交、配置项是否存在),用 isset()。值还必须非空时,用 !empty(),例如必填的文本字段。对 0 是有效值的字段要小心,因为 empty('0') 是 true。