在日常开发中,array_diff() 是一个非常实用的 PHP 内置函数。它可以用来比较两个或多个数组,返回在第一个数组中但不在后面数组中的值。这在过滤数据、比对列表差异等场景中非常常见。
那么问题来了:array_diff() 在比较值时,会进行严格的类型匹配吗?也就是说,类型不同但值相同的项,会被视为相同还是不同?
在 PHP 中,array_diff() 使用的是“非严格”的比较,也就是说,它在判断两个值是否相等时不会比较它们的数据类型,只关注值是否“相等”。
这种比较方式在 PHP 中称为“宽松比较”(loose comparison),其行为类似于使用 == 运算符进行的判断,而不是 ===。
<?php
$array1 = [1, 2, 3, "4"];
$array2 = ["1", 2, 4];
$result = array_diff($array1, $array2);
print_r($result);
?>
Array
(
[2] => 3
[3] => 4
)
在这个例子中:
1(整数) 和 "1"(字符串) 被认为是相等的,因此被过滤掉了。
3 和 "3" 不在 $array2 中,所以保留。
"4" 和 4 被认为相等,也被过滤掉。
结论:PHP 的 array_diff() 不进行严格类型比较。
虽然 array_diff() 本身不支持严格比较,但 PHP 提供了另一个函数 array_diff_assoc(),它除了比较值之外,还会比较键名。
然而,如果我们只关心值的严格比较,可以使用 array_udiff(),配合自定义的比较函数来实现严格比较。
<?php
$array1 = [1, 2, 3, "4"];
$array2 = ["1", 2, 4];
$result = array_udiff($array1, $array2, function ($a, $b) {
if ($a === $b) return 0;
return ($a > $b) ? 1 : -1;
});
print_r($result);
?>
Array
(
[0] => 1
[2] => 3
[3] => 4
)
在这个例子中,1(int) 和 "1"(string) 被视为不同的值,所以 1 被保留。这样就达到了严格类型比较的目的。
假设你有一个来自用户上传的商品 ID 列表(都是字符串),你希望剔除已经存在于数据库中的 ID(整数),可以用严格匹配的方式避免错误匹配:
<?php
$uploadedIDs = ["101", "102", "103"];
$existingIDs = [101, 104];
$diff = array_udiff($uploadedIDs, $existingIDs, function ($a, $b) {
return $a === $b ? 0 : ($a > $b ? 1 : -1);
});
// 假设你需要构造一个 URL 来展示剩余的 ID
$url = "https://m66.net/products?ids=" . implode(",", $diff);
echo $url;
?>
输出 URL:
https://m66.net/products?ids=101,102,103
array_diff() 使用的是宽松比较,不考虑类型差异;
如果需要严格匹配值类型,可以使用 array_udiff() 配合自定义比较函数;
在处理用户数据、类型敏感的数据过滤时,建议使用严格比较以避免逻辑漏洞。
希望这篇文章对你理解 PHP 中数组差异函数的行为机制有所帮助!