当前位置: 首页> 最新文章列表> 为什么布尔值在 array_diff() 中行为异常?

为什么布尔值在 array_diff() 中行为异常?

M66 2025-06-06

在日常的 PHP 编程中,array_diff() 是一个非常实用的函数,它可以用来找出两个数组之间的差异。但很多开发者在使用这个函数时可能会遇到一种奇怪的情况:

这到底是怎么回事呢?让我们一起来探究其中的原因。

1. 简单示例:布尔值的异常行为

来看下面这段代码:

$a = [true, false];
$b = [0];

$result = array_diff($a, $b);
print_r($result);

你可能会直觉地认为 truefalse 都不在数组 $b 中,所以 $result 应该是 [true, false],但实际上你会得到如下输出:

Array
(
    [0] => 1
)

是不是有点懵?为什么 false 被过滤掉了?而且 true 还变成了整数 1?我们接下来逐步拆解这个问题。

2. array_diff() 的工作方式

首先要理解 array_diff() 的底层行为。根据 PHP 官方文档 的说明:

array_diff() 使用“非严格比较”(==)来检查值是否相等。

也就是说,array_diff() 并不是使用全等 === 来比较值,而是用双等号 ==

这就意味着以下值会被认为是“相等”的:

false == 0;       // true
true == 1;        // true
true == "1";      // true
false == "";      // true

在我们的示例中,false0 判定为相等,因此被 array_diff() 排除在结果之外。

3. 布尔值会被自动转换类型

另一个细节是,array_diff() 返回的数组是数值数组,PHP 会在某些情况下对布尔值进行隐式转换。例如:

var_dump(true);  // 输出 bool(true)
echo true;       // 输出 1

print_r() 中输出时,布尔值 true 会被转换为 1。这就是为什么你会看到结果中出现了 1,而不是 true

4. 怎么避免这个问题?

如果你需要比较的数据类型比较严格(比如你真的需要区分 true1),可以使用 array_udiff() 并配合一个自定义的比较函数:

$a = [true, false];
$b = [0];

$result = array_udiff($a, $b, function($x, $y) {
    return ($x === $y) ? 0 : 1;
});

print_r($result);

输出:

Array
(
    [0] => 1
    [1] => 
)

注意,这次 false(对应值为空)也被保留了,因为我们使用了全等比较 ===

如果你需要更清晰地区分这些值并保留布尔类型的表现形式,可以结合 var_export() 来输出结果:

var_export($result);

5. 结语:谨慎处理非严格比较

array_diff() 的默认行为虽然在很多场景下表现得非常高效,但在处理布尔值、数字与字符串混合的数组时,就容易产生让人疑惑的结果。这也是 PHP 中类型弱化带来的一个典型陷阱。

在开发中,如果你对数据类型有严格要求,避免使用默认的 array_diff(),转而使用 array_udiff() 并提供自己的比较函数,是一个更安全可靠的做法。