count(null) 返回 1,因为 php 将 null 静默转为单元素数组 [null];同理 count(42)、count("hello")、count(false) 均返回 1;仅空数组和空 countable 对象返回 0。

count(null) 返回 1 而不是 0?
因为 count() 在 PHP 中对非数组、非 Countable 类型的参数会静默转为数组再计数,null 被转成空数组 [] 吗?不——恰恰相反:null 被强制转换为单元素数组 [null],所以 count(null) 实际返回 1。
- 这是 PHP 7.2 之前就存在的行为,至今未改(PHP 8.3 仍如此)
- 类似地,
count(42)、count("hello")、count(false)全都返回1 - 只有
count([])和count(new ArrayObject())这类真正为空的可数结构才返回0
怎么安全地判断“是否为空数组”
直接用 count() 判空不可靠,尤其当变量可能为 null、字符串或数字时。应先确认类型再计数。
- 最稳妥:用
is_array($var) && count($var) === 0 - 更简洁(PHP 7.3+):用
is_countable($var) ? count($var) : 0,但注意它对null返回false,不会报错 - 若只关心“逻辑上是否该算作空”,推荐
empty($var)——它对null、[]、false、0、""都返回true,但要注意empty([0])也是true(因数组含 falsy 值)
为什么 count() 不抛警告或返回 false?
PHP 的 count() 是弱类型函数,设计目标是“尽量不中断执行”。它内部调用 zend_fetch_dimension_address_read() 并 fallback 到 _count_recursive(),对非数组类型直接包装为 zval 数组结构,不触发 warning(即使 error_reporting 开到 E_ALL)。
- 这种静默转换在严格模式(
declare(strict_types=1))下也无效——count()本身不支持声明类型约束 - PHP 8.0 引入了
Countable接口,但count()对非实现该接口的对象仍走旧逻辑 - 替代方案:自己封装一个
safe_count(),先is_array()或is_countable()再调用
实际代码中容易踩的坑
常见于数据库查询结果未判空就直接 count($rows),而 $rows 实际是 null(比如 PDO::fetch() 没查到数据),导致本该跳过的逻辑被错误执行。
- 错误写法:
if (count($data) > 0) { ... }—— 当$data = null时条件为真 - 正确写法:
if (is_array($data) && !empty($data)) { ... }或if ($data !== null && is_array($data) && count($data) > 0) - 调试技巧:遇到奇怪的
count()结果,立刻加一行var_dump(gettype($var), $var);看真实类型和值
这个行为不会被修复,PHP 官方视其为“向后兼容必需”。真正要警惕的不是 count(null) 返回什么,而是你是否默认它只用于数组——它从来就不只用于数组。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











