php 8.0+ 中 count() 仅接受数组或 countable 对象,传入 null 或标量值会抛出 typeerror;应使用 is_countable() 预检,避免 @ 抑制或仅用 is_array()。

count() 传入 null 或标量值直接报错
PHP 8.0+ 对 count() 做了严格类型限制:只接受 Countable 接口实现类或数组。传 null、int、string、bool 等标量值会直接抛出 TypeError,而不是像旧版那样静默返回 0。
常见触发场景:
- 数据库查询没结果,
$rows = $pdo->fetch()返回null,却直接count($rows) - API 返回字段可能缺失,
$data['items']是null或未定义 - 函数返回值未校验,比如
$list = getItems(); count($list),而getItems()有时返回false或42
安全写法:先判断再 count(),别依赖 @ 抑制
用 is_array() 或 is_countable() 显式判断是最稳妥的。PHP 7.3+ 提供了 is_countable(),它能正确识别数组和实现了 Countable 的对象(如 ArrayObject),比单纯 is_array() 更通用。
推荐写法:
// ✅ 正确:兼容数组、Countable 对象,且排除 null/标量
if (is_countable($data)) {
$len = count($data);
} else {
$len = 0;
}
// ✅ 或更紧凑(PHP 7.4+ 空合并 + 三元)
$len = is_countable($data) ? count($data) : 0;
// ❌ 错误:@ 抑制掩盖问题,且不解决逻辑缺陷
$len = @count($data); // 仍可能触发 TypeError(PHP 8+ 不再被抑制)
// ❌ 错误:is_array() 漏掉 ArrayObject 等合法 Countable 类型
if (is_array($data)) { ... } // ArrayObject 会跳过
框架/ORM 场景下注意返回值契约
Laravel Eloquent、Doctrine、ThinkPHP 等常把“无结果”设计为返回空集合(如 Collection)或空数组,但有些自定义方法或原始 PDO 查询仍可能返回 null 或 false。不能假设所有“列表获取”操作都返回数组。
检查你调用的具体方法文档或源码,例如:
-
PDOStatement::fetch()→ 返回array|false,不是数组 -
PDOStatement::fetchAll()→ 返回array,可直接count() - Laravel
$query->get()→ 总是Collection(实现了Countable) - Laravel
$query->first()→ 返回模型实例或null,不能count()
遇到不确定返回类型的函数,优先查它的 PHPDoc 或测试输出 var_dump(gettype($x), $x)。
全局兜底?不建议重写 count() 函数
有人想用 function count($v) { return is_countable($v) ? \count($v) : 0; } 覆盖原生函数。这在 Composer 自动加载或命名空间环境下极易冲突,且违反直觉——其他开发者读到 count() 默认认为是 PHP 原生行为。
真正该做的是:
- 在项目入口或基础工具类中提供一个语义明确的辅助函数,比如
safe_count($value) - 用静态分析工具(如 PHPStan)配置规则,检测
count()的非法参数类型 - 在 CI 中开启
error_reporting = E_ALL,让这类错误在测试阶段暴露
类型错误不是边缘情况,而是明确的契约破坏。修复它需要定位源头数据流,而不是在调用点打补丁。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











