PHP 8.2 中 array_filter 默认按 empty() 规则过滤,会误删合法值如 0、"0"、false 等;应显式写回调并用 !== 严格判断,保留原始键名,需用键或外部变量时须指定标志和 use,多维数组需手动递归处理。

PHP 8.2 中 array_filter 用得准不准,关键不在会不会写,而在是否清楚它默认怎么“判真假”、键名怎么留、回调怎么传参。稍不注意,0 被删、false 被误杀、键名丢了、外部变量用不上——全在一行代码里发生。
别依赖默认行为,显式写回调判断空值
默认不传回调时,array_filter($arr) 会按 PHP 的 empty() 规则过滤:0、"0"、false、null、''、[] 全被干掉。业务中 0 往往是合法数值(比如库存、评分、开关状态),不能丢。
- 用严格比较
!==区分类型和值,例如:array_filter($arr, fn($v) => $v !== null && $v !== '' && $v !== []) - 如果
false是有效值(如布尔配置项),就别加$v !== false;如果是错误标记才过滤 - 对浮点数 0.0,需单独判断:
!is_float($v) || $v != 0.0,避免和整型 0 混淆
要保留原始键名,就别碰 array_values()
array_filter 默认保留所有原始键名(包括关联键和数字索引),这是它的设计特性。很多人写完过滤又跟一个 array_values(),等于主动放弃键名,还多一次遍历。
- 确认需求:是否真需要重排索引?多数表单数据、配置数组、API 返回都依赖键名
- 只要不调
array_values(),键就稳稳在原位;索引不连续是正常现象,PHP 数组完全支持 - 若必须用数字索引且连续,等过滤完再统一处理,不要嵌套在过滤链里
要用键名或外部变量,必须显式声明参数和作用域
回调函数默认只接收值($value)。想用键($key)或外部变量(如阈值、配置),不设标志、不用 use 就拿不到。
立即学习“PHP免费学习笔记(深入)”;
- 根据键过滤(如跳过特定字段):
array_filter($arr, fn($v, $k) => $k !== 'password', ARRAY_FILTER_USE_BOTH) - 引用外部变量(如最小长度限制):
$minLen = 3; array_filter($arr, fn($s) => is_string($s) && strlen($s) >= $minLen, use($minLen)) - 只传键名过滤(少见但存在):
array_filter($arr, fn($k) => strpos($k, 'id') !== false, ARRAY_FILTER_USE_KEY)
多维数组或特殊类型要额外小心
array_filter 不递归,也不自动识别资源、对象、闭包。遇到嵌套结构或非标类型,容易静默失败或报错。
- 过滤二维数组的子项,需手动递归:
array_map(fn($sub) => array_filter($sub, $cb), $arr) - 对象属性不能直接过滤,先转成数组:
array_filter((array)$obj, $cb)(注意受访问控制影响) - 资源(如 file handle)、闭包、不可序列化对象,在回调中做
is_scalar()或is_string()类型检查,避免警告



















