需要从数组里筛选出符合条件的元素?array_filter()就是干这个的。它遍历数组的每个元素,传给回调函数判断,回调返回true的就保留,false的就过滤掉。
不传回调函数的话,它会自动过滤掉所有“假值”(空字符串、0、null、false等)。这个函数从PHP 4.0.6就有了。
语法格式
array array_filter(array $array [, callable $callback = null [, int $mode = 0 ]]): array
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| array | 要过滤的数组 | 必填 |
| callback | 回调函数,返回true保留,false过滤 | 可选 |
| mode | 决定传给回调的参数类型 | 可选 |
mode参数取值:
-
0(默认):只传值 -
ARRAY_FILTER_USE_KEY:只传键名 -
ARRAY_FILTER_USE_BOTH:同时传值和键名
返回值: 过滤后的新数组,原数组的键名会保留。
示例1:不过回调函数(自动过滤假值)
<?php
$data = [
"PHP教程",
"",
0,
null,
false,
"JavaScript",
42,
[]
];
$filtered = array_filter($data);
print_r($filtered);
?>
输出:
Array
(
[0] => PHP教程
[5] => JavaScript
[6] => 42
)
空字符串、0、null、false、空数组都被自动过滤掉了。只保留了“真值”。注意键名保留了原来的位置(0、5、6)。
示例2:自定义回调函数(按条件过滤)
<?php
$scores = [85, 92, 47, 78, 88, 35, 96, 52];
// 只保留及格成绩(>=60)
$passed = array_filter($scores, function($score) {
return $score >= 60;
});
print_r($passed);
?>
输出:
Array
(
[0] => 85
[1] => 92
[3] => 78
[4] => 88
[6] => 96
)
47分、35分、52分被过滤掉了。键名还是原来的0、1、3、4、6,没重新索引。如果需要连续索引,外面包一层array_values()。
示例3:用ARRAY_FILTER_USE_KEY(根据键名过滤)
<?php
$students = [
"code001" => "张伟",
"code002" => "李芳",
"code003" => "王磊",
"code004" => "赵敏",
"admin" => "管理员"
];
// 只保留以code开头的学生(过滤掉admin)
$regular_students = array_filter($students, function($key) {
return strpos($key, "code") === 0;
}, ARRAY_FILTER_USE_KEY);
print_r($regular_students);
?>
输出:
Array
(
[code001] => 张伟
[code002] => 李芳
[code003] => 王磊
[code004] => 赵敏
)
注意第三个参数ARRAY_FILTER_USE_KEY告诉函数把键名传给回调,而不是值。
示例4:用ARRAY_FILTER_USE_BOTH(同时使用键和值)
<?php
$products = [
"KB001" => ["name" => "机械键盘", "price" => 299],
"MS002" => ["name" => "游戏鼠标", "price" => 89],
"DP003" => ["name" => "显示器", "price" => 1250],
"HP004" => ["name" => "耳机", "price" => 350]
];
// 过滤掉价格超过500的商品
$affordable = array_filter($products, function($value, $key) {
return $value["price"] <= 500;
}, ARRAY_FILTER_USE_BOTH);
print_r($affordable);
?>
输出:
Array
(
[KB001] => Array
(
[name] => 机械键盘
[price] => 299
)
[MS002] => Array
(
[name] => 游戏鼠标
[price] => 89
)
[HP004] => Array
(
[name] => 耳机
[price] => 350
)
)
回调同时收到键名$key和值$value,可以做更灵活的筛选逻辑。
个人经验分享
-
常见使用场景
-
过滤空值:
$non_empty = array_filter($data);(最常用) -
数据验证:只保留符合规则的数据
-
权限过滤:根据条件筛选用户列表
-
搜索功能:模糊匹配后返回符合条件的结果
-
-
和array_map()的区别
-
array_filter():筛选,元素个数可能减少 -
array_map():转换,元素个数不变
-
-
性能方面
array_filter()效率很高。但注意:如果数组很大(几万条),回调函数里不要做太重的操作。 -
注意0和false的区别
默认行为会过滤掉整数值0。如果0是你的有效数据,需要自定义回调:$data = [0, 1, 2, 0, 3]; // 默认会过滤掉0 $result1 = array_filter($data); // [1,2,3] // 想保留0,回调明确判断 $result2 = array_filter($data, function($v) { return $v !== false && $v !== null && $v !== ''; }); // [0,1,2,0,3] -
重新索引的两种方式
$filtered = array_filter($data); // 方式一:array_values $reindexed = array_values($filtered); // 方式二:手动foreach重新组装
示例5:代码号学习编程场景
<?php
// 场景:学生成绩分析,筛选出成绩优秀和不及格的学生
$students = [
"code001" => 85,
"code002" => 92,
"code003" => 47,
"code004" => 78,
"code005" => 96,
"code006" => 38,
"code007" => 88,
"code008" => 55
];
// 优秀:>=85
$excellent = array_filter($students, fn($score) => $score >= 85);
// 不及格:<60
$failed = array_filter($students, fn($score) => $score < 60);
echo "优秀学生:\n";
print_r($excellent);
echo "\n不及格学生:\n";
print_r($failed);
?>
输出:
优秀学生:
Array
(
[code002] => 92
[code005] => 96
[code007] => 88
)
不及格学生:
Array
(
[code003] => 47
[code006] => 38
[code008] => 55
)
示例6:多维数组过滤
<?php
$orders = [
["id" => 1001, "status" => "completed", "amount" => 299],
["id" => 1002, "status" => "pending", "amount" => 89],
["id" => 1003, "status" => "completed", "amount" => 1250],
["id" => 1004, "status" => "cancelled", "amount" => 350],
["id" => 1005, "status" => "pending", "amount" => 199]
];
// 筛选出待处理的订单
$pending_orders = array_filter($orders, function($order) {
return $order["status"] === "pending";
});
// 筛选出金额大于200的已完成订单
$large_completed = array_filter($orders, function($order) {
return $order["status"] === "completed" && $order["amount"] > 200;
});
echo "待处理订单数:" . count($pending_orders) . "\n";
print_r($pending_orders);
?>
本节课程知识要点
-
array_filter()根据回调函数返回值筛选数组元素 -
不传回调时,自动过滤
false、null、0、""、[]等假值 -
回调返回
true保留,false过滤 -
mode参数可指定传给回调的是值、键名、还是两者 -
原数组的键名会被保留(不会自动重排索引)
-
多维数组也可以正常过滤
-
从PHP 4.0.6开始可用