In daily PHP programming, array_diff() is a very practical function that can be used to find the difference between two arrays. But many developers may encounter a strange situation when using this function: when the array contains boolean values, the behavior of array_diff() seems to become "abnormal".
What's going on? Let's explore the reasons together.
Let's take a look at the following code:
$a = [true, false];
$b = [0];
$result = array_diff($a, $b);
print_r($result);
You might intuitively think that true and false are not in the array $b , so $result should be [true, false] , but you will actually get the following output:
Array
(
[0] => 1
)
Are you a little confused? Why is false filtered out? And true also becomes an integer 1 ? Let's gradually disassemble this problem.
First, we need to understand the underlying behavior of array_diff() . According to the instructions of the official PHP documentation :
array_diff() uses "non-strict comparison" (==) to check if the values are equal.
That is to say, array_diff() does not use congruent == to compare values, but uses double equal sign == .
This means that the following values will be considered "equal":
false == 0; // true
true == 1; // true
true == "1"; // true
false == ""; // true
In our example, false is judged equal by 0 and is therefore excluded from the result by array_diff() .
Another detail is that the array returned by array_diff() is an array of numeric values, and PHP will implicitly convert Boolean values in some cases. For example:
var_dump(true); // Output bool(true)
echo true; // Output 1
When output in print_r() , the boolean true is converted to 1 . That's why you'll see 1 appearing in the result, not true .
If you need to compare the data types (for example, you really need to distinguish between true and 1 ), you can use array_udiff() and cooperate with a custom comparison function:
$a = [true, false];
$b = [0];
$result = array_udiff($a, $b, function($x, $y) {
return ($x === $y) ? 0 : 1;
});
print_r($result);
Output:
Array
(
[0] => 1
[1] =>
)
Note that false (the corresponding value is empty) is also preserved this time, because we used congruent comparison === .
If you need to distinguish these values more clearly and preserve the representation of Boolean type, you can combine var_export() to output the result:
var_export($result);
Although the default behavior of array_diff() is very efficient in many scenarios, it is easy to produce confusing results when dealing with arrays of boolean values, numbers and strings. This is also a typical trap caused by type weakening in PHP.
In development, if you have strict requirements on data types, avoid using the default array_diff() and instead use array_udiff() and provide your own comparison function, it is a safer and more reliable approach.