PHP 7.2+ 的 count() 报警告是因为仅接受数组或 Countable 对象,传入 null、字符串等会触发 Warning;本质是类型安全增强,暴露了未初始化变量、未校验 API 返回值等隐患。

为什么 PHP 7.2+ 的 count() 会报这个警告
PHP 7.2 起,count() 对参数类型做了严格校验:只接受数组或实现了 Countable 接口的对象。传入 null、false、字符串、整数 或未定义变量时,不再静默转为 0 或 1,而是直接抛出 Warning: count(): Parameter must be an array or an object that implements Countable。
这不是 bug,是 PHP 类型安全增强的表现。旧项目在 PHP 5.6/7.1 下能“侥幸运行”,切到 7.2+ 后立刻暴露问题——本质是代码里存在变量未初始化、API 返回值未判断、数据库查询失败未兜底等隐患。
快速定位高危 count() 调用位置
别靠肉眼翻代码。用命令行批量扫描:
-
Windows(phpEnv 常见环境):在项目根目录打开 CMD,执行:
findstr /s /i "count(" *.php | findstr /v "is_countable\|is_array\|isset\|array)" -
Linux/macOS:执行:
grep -r "count(" . --include="*.php" | grep -v "is_countable\|is_array\|isset\|array)" | head -15
重点关注这些上下文:
• count($_POST[...])、count($_GET[...]) —— 没判 isset() 或空值
• count(json_decode(...)) —— 没检查 json_last_error()
• count($db->fetch()) —— PDO/MySQLi 查询结果可能是 false
• 类属性如 protected $errors; 仅声明未初始化(常见于 PHPGraphLib 等老库)
立即学习“PHP免费学习笔记(深入)”;
推荐修复方式:优先用 is_countable() 判断
PHP 7.3+ 原生支持,语义准确、无副作用、兼容未来版本:
- ✅ 正确写法:
if (is_countable($data)) { $len = count($data); } else { $len = 0; } - ✅ 单行简写:
$len = is_countable($data) ? count($data) : 0; - ❌ 避免
@count($data)—— 错误被吞掉,后续逻辑可能因$len异常而错乱 - ❌ 少用
is_array($data)替代 —— 它漏掉实现了 Countable 的对象(如 Laravel Collection、Doctrine ArrayCollection)
其他安全补充方案
当无法升级 PHP 或需兼容更低版本时,可选以下方式:
-
强制转数组(适合 WordPress、简单业务场景):
count((array)$data)——null、false、字符串都会变成合法数组,但注意:字符串"abc"会转成['abc'],语义是否合理需结合业务判断 -
显式初始化类属性(修复老库根本问题):
找到类似protected $errors;的声明,改为protected $errors = [];—— 符合 PSR-12 规范,一劳永逸 -
临时调试绕过(仅限本地/测试环境):
在出错脚本顶部加error_reporting(E_ALL & ~E_WARNING);,不改 php.ini,作用域可控
真正要解决的,从来不是 warning 本身,而是它背后暴露的数据不确定性——比如从外部接口拿数据不校验、函数返回值不验证、对象属性不初始化。修复一处 count(),顺手把源头逻辑补牢,才是长久之计。



















