array_filter() 默认删不掉0是错觉,实际会误删0、"0"等假值;正确做法是用回调函数严格判断null、空字符串和空数组,保留0和"0"等有效值。

PHP array_filter() 默认行为为什么删不掉 0?
因为 array_filter() 默认用「布尔上下文」判断元素真假,而 0、"0"、0.0、空数组 [] 都会被转成 false,直接被过滤掉——这不是你想要的「只去空值」,而是连合法的数字零也误删了。
常见误操作:array_filter($arr) → 会吃掉所有 0、"0"、null、""、false
真正需要的是:保留 0 和 "0",只剔除 null、""、[] 等真正无意义的空值。
怎么只过滤 null/空字符串/空数组,但保留 0 和 "0"?
必须显式传入回调函数,用严格比较或类型感知逻辑:
- 用
=== null排除null,但留0 - 用
=== ""排除空字符串,但留"0" - 用
is_array($v) && empty($v)排除空数组,但留[0]
推荐写法:
立即学习“PHP免费学习笔记(深入)”;
$clean = array_filter($arr, function($v) {
return $v !== null && $v !== '' && !($v === [] || (is_array($v) && empty($v)));
});
注意:如果数组含对象,empty($obj) 始终为 false,无需额外处理;若需过滤不可遍历对象,得加 is_object($v) && !$v instanceof Traversable 判断。
遇到 "0" 字符串要不要留?看业务场景
很多配置项(如数据库字段、API 参数)里 "0" 是有效值,比如开关状态、分页页码、评分下限。误删会导致逻辑错乱。
如果你确定要同时剔除 "0" 和 0,说明你其实要的是「数值为 0 的假值」,那就该用:
$clean = array_filter($arr, function($v) {
return $v || (is_string($v) && $v !== '0') || (is_numeric($v) && $v != 0);
});
但这种写法极易出错,更稳妥的是先统一类型再过滤,比如强制转整型再比对,或从业务层提前归一化输入。
性能和键名保留要注意什么?
array_filter() 默认**重置键名**,如果你依赖原始数字索引(如表单多维数组),必须加 ARRAY_FILTER_USE_KEY 或手动重建键:
- 保留原键:
array_filter($arr, $callback, ARRAY_FILTER_USE_BOTH) - 或过滤后用
array_values()重排,或用array_merge([]强制重索引 - 大数组慎用嵌套
empty()—— 对大数组调用empty($v)在 PHP 7.4+ 性能尚可,但 PHP 8.0+ 对非数组类型已优化,不必过度担心
最易被忽略的一点:0.0、-0、"0.0" 这些浮点边界值,是否算「空」取决于业务定义,PHP 默认不会把它们当空,但你的回调里若用了 !$v 就会误判。











