array_filter() 是过滤索引数组空值最直接方法,但保留原键名需用 array_values() 重置;若需保留 0/false 则须传回调函数;array_diff() 因松散比较等问题不适用;多维数组需按业务逻辑定制判断;PHP 8.0+ 需严格匹配回调参数数量与标志。

用 array_filter() 去掉索引数组里的空值最直接
array_filter() 默认就过滤掉所有“falsy”值(null、false、0、''、[]),对纯索引数组很友好。但要注意:它会保留原键名,不是重排索引的。
常见错误是以为过滤后还是连续数字键 —— 实际上键没变,比如 [0 => 'a', 2 => '', 4 => 'b'] 过滤后变成 [0 => 'a', 4 => 'b'],直接用 $arr[1] 就会出错。
- 如果只要值、不要原键,加
array_values()重置索引:array_values(array_filter($arr)) - 如果只想过滤空字符串和
null,但保留0和false,必须传回调函数:array_filter($arr, function($v) { return $v !== '' && $v !== null; }) - PHP 7.4+ 可用箭头函数简写:
array_filter($arr, fn($v) => $v !== '')
为什么 array_diff() 不适合单独过滤空值
array_diff($arr, ['', null, false, 0]) 看似能“减掉”空值,但问题很多:
-
false和0在松散比较下会被当成相等,array_diff内部用的是松散比较,可能误删有效数值 - 无法区分
0和字符串'0'—— 两者都会被当成0比较 - 如果数组里有
0.0或0.00,也可能被意外匹配 - 性能比
array_filter()差,尤其大数组时要遍历多次
处理多维索引数组时不能只套一层 array_filter()
比如 $data = [['name' => 'a', 'age' => 0], ['name' => '', 'age' => 25]],想删掉 'name' 为空的子数组 —— 这时候得写明确逻辑:
立即学习“PHP免费学习笔记(深入)”;
$filtered = array_filter($data, function($item) {
return !empty($item['name']); // 注意:这里用 !empty() 而不是 $item['name'] !== ''
});
因为 empty() 对 null、''、0、[] 都返回 true,而你可能需要保留 0(比如年龄字段)。所以实际判断前得先确认业务语义:“空”到底指什么。
- 字段允许为
0?那就别用empty(),改用严格比较 - 字段是字符串且不允许空白?用
trim($item['name']) !== '' - 不确定键是否存在?先用
isset($item['name'])做兜底
注意 array_filter() 在 PHP 8.0+ 的行为变化
PHP 8.0 开始,array_filter() 默认保留键名的行为没变,但如果你传了 ARRAY_FILTER_USE_KEY 或 ARRAY_FILTER_USE_BOTH 标志,回调函数签名必须匹配,否则报 TypeError。
比如这个在 PHP 7.x 能跑,在 8.0+ 会崩:
// ❌ 错误:PHP 8.0+ 要求参数个数与标志严格对应
array_filter($arr, function($v, $k) { return $k % 2 === 0; }, ARRAY_FILTER_USE_BOTH);
正确写法是确保参数数量一致:
// ✅ 正确:两个参数,且用了 ARRAY_FILTER_USE_BOTH
array_filter($arr, function($v, $k) { return $k % 2 === 0; }, ARRAY_FILTER_USE_BOTH);
// ✅ 或者只用一个参数,不传标志(默认行为)
array_filter($arr, function($v) { return $v !== ''; });
线上环境若跨 PHP 版本,这点容易漏测 —— 尤其是老项目升级时。



















