array_filter()是PHP筛选数组的唯一推荐原生方式,不修改原数组、返回新数组、支持任意callable,需显式返回布尔值,键名默认保留,可配合array_values()重索引。

用 array_filter() 配合自定义函数最直接
PHP 里筛选数组,array_filter() 是唯一推荐的原生方式。它不修改原数组,返回新数组,且天然支持传入任意 callable —— 包括匿名函数、命名函数、静态方法等。
关键点:必须显式返回布尔值(true 留下,false 过滤),否则 PHP 会按“空值”逻辑隐式转换,容易漏掉 0、''、null 等合法值。
- 如果自定义函数没写
return,或返回了未定义变量,结果不可预测 - 默认保留键名,如需重索引,包一层
array_values() - PHP 7.4+ 支持箭头函数,适合单行逻辑:
array_filter($arr, fn($v) => $v > 10)
自定义函数里怎么访问外部变量?
闭包(匿名函数)用 use 关键字导入,比全局变量安全,也比反复传参清爽。
$min = 5;
$max = 20;
$result = array_filter($numbers, function($n) use ($min, $max) {
return $n >= $min && $n <= $max;
});
注意:use 默认传值,如需引用外部变量(比如计数器),得加 &:use (&$count)。但筛选场景极少需要改外部变量,多数情况传值就够了。
立即学习“PHP免费学习笔记(深入)”;
- 不要在
use里传大数组或对象,可能引发内存问题 - 命名函数无法直接
use,得靠参数传递或闭包包装
为什么 foreach 手动遍历不是好选择?
虽然能跑通,但破坏函数式习惯,代码冗长,且容易出边界错误。
- 手动
unset()会导致键名错乱,后续for循环可能跳过元素 - 新建数组再
push多一次内存分配,性能不如array_filter()内部优化 - 无法链式调用(比如接
array_map()或array_values()) - 多人协作时,
foreach筛选逻辑分散,不易定位意图
遇到对象数组怎么筛?
一样用 array_filter(),只是回调里访问对象属性即可。注意属性可见性 —— 私有/受保护属性需通过 getter,或确保在类作用域内调用。
$users = [new User('Alice', 25), new User('Bob', 17)];
$adults = array_filter($users, fn($u) => $u->age >= 18);
若对象来自 JSON 解码(stdClass),属性直接用 ->name;若为关联数组形式的对象(json_decode($json, true)),就用 ['name']。
- 别在回调里做耗时操作(如数据库查询),会显著拖慢整个过滤过程
- 空对象或
null元素要提前判断,否则->prop会报Trying to get property 'xxx' of non-object
for 循环时,不重索引很容易踩坑。











