array_filter 默认过滤所有 falsy 值(空字符串、0、0.0、null、false、空数组及字符串"0"),返回保留原键名的新数组;需显式回调才能保留"0"等有意义的 falsy 值,必要时用 array_values 重排索引。

array_filter 会过滤掉哪些值
array_filter 默认只保留「被判定为 true」的元素,也就是对每个值调用 empty() 的反向逻辑:空字符串、0、0.0、null、false、空数组都会被过滤掉。注意:"0"(字符串零)也会被删——这是最容易踩的坑。
常见错误现象:["a", "0", "b"] 经 array_filter 后只剩 ["a", "b"],不是 bug,是默认行为。
- 若想保留
"0"或其他“falsy 但有意义”的值,必须传入回调函数 - 不传回调时,
array_filter不关心键名,只按值判断 - 原数组的键名会被保留(非数字索引不会重排),需要重索引得套一层
array_values()
怎么写回调函数才能保留字符串 "0"
关键在于别依赖 PHP 隐式类型转换。显式比对类型和值,比如检查是否为非空字符串:
array_filter($arr, function($v) {
return is_string($v) ? $v !== "" : (bool) $v;
});
更稳妥的做法是按业务定义“有效”:比如只留非空字符串、非 null 数字、非空数组:
is_string($v) && trim($v) !== ""-
is_numeric($v) || is_bool($v)(注意true/false仍会被当 bool 处理) - 避免直接
return $v—— 它等价于默认行为
array_filter 会改变原数组吗
不会。array_filter 总是返回新数组,原数组完全不变。这点和 sort()、unset() 等就不同。
使用场景:需要在不影响原始数据的前提下提取子集,比如从请求参数中筛出非空字段:
$safe_input = array_filter($_POST, 'strlen'); // 用 strlen 避开 "0" 被删
- 传入的回调必须可调用,否则触发
Warning: array_filter(): expects parameter 2 to be a valid callback - PHP 7.4+ 支持箭头函数,但注意它不能访问外部变量(除非用
use) - 性能上,
array_filter是单次遍历,O(n),无明显瓶颈
为什么 array_filter 返回的键名乱了
因为它是按原键名保留的。比如 [0 => 1, 1 => "", 2 => 3] 过滤后是 [0 => 1, 2 => 3],中间缺了键 1。如果后续要 for 循环或 JSON 输出,可能出问题。
解决方法很简单:
- 要重排索引:包一层
array_values(array_filter(...)) - 要保留键但确保是字符串键:不用动,JSON 编码时自动处理
- 误以为
array_filter会“压缩”键名,其实是误解它的设计目标——它只管值,不管键结构
真正容易被忽略的是:你传进去的数组如果有字符串键(如 ['id' => 123, 'name' => '']),过滤后 'id' 还在,'name' 消失,键名语义没丢,但开发者常忘了检查键是否存在而非只看值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











