当前位置: 首页> 最新文章列表> PHP 中 array_filter() 性能分析:使用回调函数与默认行为,哪种方式更高效?

PHP 中 array_filter() 性能分析:使用回调函数与默认行为,哪种方式更高效?

M66 2025-05-17

在 PHP 中,array_filter() 是一个非常常用的数组处理函数,主要用于过滤数组中的元素。这个函数可以接收一个可选的回调函数,用来定义哪些元素应该保留。如果没有提供回调函数,array_filter() 会自动去除数组中值为 falsenull0、空字符串和空数组等“假值”的元素。

那么问题来了:在实际使用中,array_filter() 使用默认行为与提供自定义回调函数之间,在性能上有什么差异?哪种方式更高效?

本文将通过对比测试这两种用法的执行时间,从性能的角度进行深入分析。

一、基本语法回顾

// 默认行为:移除数组中的“假值”
$result = array_filter($array);

// 使用回调函数:只保留大于 0 的值
$result = array_filter($array, function($value) {
    return $value > 0;
});

二、测试代码示例

我们构造一个包含大量元素的数组,并分别使用默认行为与自定义回调函数来过滤它们。

function testArrayFilterDefault($array) {
    $start = microtime(true);
    $result = array_filter($array);
    return microtime(true) - $start;
}

function testArrayFilterCallback($array) {
    $start = microtime(true);
    $result = array_filter($array, function($value) {
        return $value > 0;
    });
    return microtime(true) - $start;
}

// 构造测试数组,包含 100000 个元素
$testArray = [];
for ($i = 0; $i < 100000; $i++) {
    $testArray[] = $i % 2 === 0 ? 0 : $i; // 一半是 0,一半是整数
}

// 执行测试
$timeDefault = testArrayFilterDefault($testArray);
$timeCallback = testArrayFilterCallback($testArray);

echo "默认行为执行时间:{$timeDefault} 秒\n";
echo "回调函数执行时间:{$timeCallback} 秒\n";

三、性能分析结果

运行上面的脚本,你会发现默认行为在绝大多数情况下执行得更快。原因如下:

  • 默认行为是 C 语言层实现的内建逻辑,执行效率更高。

  • 使用回调函数时,PHP 每次都需要调用用户自定义的函数,函数调用开销不容忽视,尤其是在大量数据时。

示例输出(根据具体机器略有不同):

默认行为执行时间:0.012345 秒
回调函数执行时间:0.035678 秒

可以看到,默认行为大约快了两到三倍

四、是否总是应该使用默认行为?

虽然默认行为性能更优,但它有局限性——只能去除“假值”。如果你的过滤逻辑稍微复杂,比如保留特定范围的数值、类型检查等,依然需要回调函数。

例如:

// 保留奇数值
array_filter($array, function($v) {
    return $v % 2 !== 0;
});

这显然不能通过默认行为实现。

五、真实案例:过滤用户提交的表单数据

$userInput = [
    'name' => 'Alice',
    'email' => '',
    'age' => 0,
    'newsletter' => false,
];

$cleanedInput = array_filter($userInput); // 只保留非假值字段

// 输出 ['name' => 'Alice']

在这个例子中,如果你希望移除所有未填写的字段(包括 false、空字符串等),默认行为就非常合适。而如果你希望只保留非空字符串字段,则需要使用回调:

$cleanedInput = array_filter($userInput, function($value) {
    return is_string($value) && trim($value) !== '';
});

六、总结

使用方式性能灵活性使用场景
默认行为? 高效? 受限去除假值
使用回调函数? 稍慢? 灵活自定义过滤逻辑

建议:如果只是移除假值,使用默认行为即可;如果需要更复杂的逻辑,使用回调函数无可避免。