合并数组后需用带回调的array_filter()过滤,仅剔除null、''、[]等真正空值,保留0、false等业务有效值,并根据数据契约明确定义“空”的标准。

合并数组后直接用 array_filter() 会误删 0 和 false
PHP 合并数组(比如用 array_merge() 或 +)之后,如果直接调用 array_filter($arr)(不带回调),它会把所有“falsy”值都干掉:包括 null、''、false、0、0.0、空数组 []。这在多数业务场景里是错的——比如商品价格为 0 元、开关状态为 false,不该被当成“空值”删掉。
- 只过滤真正意义上的“空”:常见的是
null、''(空字符串)、[](空数组) - 保留
0、false、'0'、'false'等有业务含义的值 - 如果合并后是多维数组(如 API 返回的嵌套结构),需避免用默认
array_filter(),否则可能漏判或误判
按需写回调:明确哪些算“空”
合并后的数组类型不确定,必须用带回调的 array_filter() 才可控。关键不是“什么不为空”,而是“什么算空”——根据你的数据契约来定义。
例如,合并后得到一个用户列表,每个元素是关联数组,你要过滤掉 'name' 为空字符串或 null 的项:
$merged = array_merge($listA, $listB);
$filtered = array_filter($merged, function ($user) {
return !is_null($user['name']) && $user['name'] !== '';
});
- 用
is_null()判null,比== null更安全 - 用严格比较
!== ''避免把'0'、'false'当空字符串误删 - 访问键前最好加
isset($user['name'])防 Notice,尤其合并来源不一致时
合并 + 过滤后要重索引?小心键名残留
array_filter() 默认保留原键名,合并后的数组若含数字键,过滤后可能变成稀疏索引(如 [0 => 'a', 2 => 'c', 5 => 'f'])。后续用 for 循环或 array_values() 时容易出错。
立即学习“PHP免费学习笔记(深入)”;
- 需要连续数字索引 → 补一句
array_values(array_filter(...)) - 是关联数组且依赖键名(如配置项映射)→ 不要重索引,保持原键更安全
- 用
foreach遍历时不受影响,无需处理
多维数组深层过滤别硬套一层 array_filter()
如果合并结果是二维/三维数组,而你想过滤掉子数组中某个字段为空的整条记录(比如 ['id' => 1, 'title' => ''] 整个剔除),不能只对顶层调用 array_filter()。
正确做法是传入回调,针对子项判断:
$merged = [...]; // 每个元素是 ['id' => ..., 'title' => ...] $filtered = array_filter($merged, fn($item) => !empty($item['title']));
-
!empty($item['title'])能同时覆盖null、''、未定义,但注意它也会把0、false当空 —— 如果title可能是数字 ID,就得换用isset($item['title']) && $item['title'] !== '' - 不要试图用
array_map()套array_filter()来“递归清理”,那会改变结构,大概率不是你想要的 - 真要深度过滤(比如清空所有子级里的空字符串),得自己写递归函数,或用
array_walk_recursive()配合引用修改
最易被忽略的一点:合并操作本身可能引入重复键或意外类型(比如一个数组含 int 键,另一个含 string 键),导致 array_filter() 回调里访问字段时触发 Notice。上线前务必用实际数据跑一遍,别只测理想 case。



















