应优先使用 array_filter() 而非 foreach + unset;回调须显式返回布尔值,PHP 8.3 对类型更严格;默认保留键名,按键过滤需指定 flag;不传回调会误删 0/false 等 falsy 值。

直接用 array_filter(),别手写 foreach + unset —— 它专为这事设计,语义清、不改原数组、性能稳。
回调函数必须返回布尔值,否则逻辑会悄悄错
回调里返回非布尔值(比如字符串 "yes"、数字 1 或 null)会被 PHP 隐式转成 bool,容易误判:
-
return $num % 13;→ 当$num === 0时返回0(即false),但你本意可能是“保留非零值”,结果全丢了 - 正确写法是显式比较:
return $num % 13 !== 0;或return (bool) $num; - PHP 8.3 起更严格:若回调声明了类型(如
function(int $n)),而数组含null或字符串,会直接报TypeError,不是静默转换
键名默认不重置,JSON 或 for 循环前要加 array_values()
array_filter() 返回的新数组保留原始键名,不是 [0, 1, 2] 连续索引:
- 输入
[53, 182, 435, 591, 637],过滤后可能是[0 => 53, 2 => 435, 3 => 591] - 前端 JSON 解析、
for ($i = 0; $i 、或某些框架要求紧凑索引时,必须补上 <code>array_values() - 常见写法:
$result = array_values(array_filter($arr, $callback)); - 但若你依赖键名(比如键是用户 ID:
['u101' => 'Alice', 'u102' => 'Bob']),反而要避免array_values()—— 键名本身就是业务数据
要按键名或键值组合过滤,必须传第三个 flag 参数
默认只传值给回调,想访问键名?得加 ARRAY_FILTER_USE_KEY 或 ARRAY_FILTER_USE_BOTH:
立即学习“PHP免费学习笔记(深入)”;
- 只按键筛选(如保留所有以
user_开头的键):array_filter($arr, fn($key) => str_starts_with($key, 'user_'), ARRAY_FILTER_USE_KEY) - 键值都要(如只留“值非空且键含
id”的项):array_filter($arr, fn($val, $key) => $val !== '' && str_contains($key, 'id'), ARRAY_FILTER_USE_BOTH) - 注意:
fn($val, $key)形式在 PHP 8.1+ 才支持双参数;PHP 8.0 及以下只能用ARRAY_FILTER_USE_BOTH+ 匿名函数,并确保回调签名匹配
不传回调时默认删所有 falsy 值,0 和 false 也会消失
写 array_filter($arr) 看似省事,但会无声干掉 0、false、''、null、[] —— 这在处理状态码、ID、开关字段时极危险:
- 例如
array_filter([0, 1, 'active', false])→[1 => 1, 2 => 'active'],0和false全没了 - 要保留
0但过滤空字符串?必须显式写回调:array_filter($arr, fn($v) => $v !== '') - 调试时可用
var_dump(array_keys($arr), array_filter($arr))对比前后键名和值,快速定位是否被默认行为误删
最易被忽略的是:回调签名兼容性(尤其升级到 PHP 8.3 后)、falsy 值的隐式删除、以及键名保留这个“特性”在不同场景下到底是优点还是坑——它不报错,但结果可能完全不符合预期。



















