[英]Why does in_array() return unexpected / strange results?
为什么in_array()
有时表现得如此奇怪并且会返回如此意外的结果?
我们来看几个例子:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue)); // returns bool(true)
var_dump(in_array(0, $arrayWithNull)); // returns bool(true)
var_dump(in_array(true, $arrayWithMinusOne)); // returns bool(true)
咦? 这里发生了什么事!?
(几年前,我开始对这种奇怪的行为感到疑惑。我认为这对某些人来说可能有用,因此我输入了这个问题。)
使用in_array()
始终使用第三个参数strict true
:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue, true)); // returns bool(false)
var_dump(in_array(0, $arrayWithNull, true)); // returns bool(false)
var_dump(in_array(true, [-1], true)); // returns bool(false)
因此,当您使用in_array()
并将true
作为第三个参数时,搜索值与数组之间的比较是严格完成的,这意味着in_array()
工作方式与您可能期望的一样。
(参数strict也在php.net文档中描述。)
如果没有将参数strict设置为true,则搜索值与数组的每个值之间的比较是通过相等而不是通过标识来完成的。 这意味着值的类型无关紧要,因此PHP将值内部转换为相同的数据类型,以便能够比较它们。
这意味着在第一个示例中,搜索到的值'Gary'
在与true
进行比较时会转换为布尔值,因此会导致true
与true
的比较,这显然是true
。
第二个数组也是如此,其中0
最后与null
进行比较,结果为true
,即使0
显然与null
(例如,当您处理数字和/或函数结果时,这可能特别棘手,其中null
可以表示空值而不是0
)。
然后第三个数组看起来很奇怪,因为我们检查数组中的值true
,它只包含-1
,但in_array()
仍然返回true
以进行比较。 在这种情况下, -1
将转换为布尔值true
。 所以两个方向的问题都是一样的。
您可以在此Stack Overflow答案中找到有关PHP中比较问题的更多示例(因为这与==
/ ===
相同)。
不幸的是,调用in_array()
时strict参数的默认值是......好吧,是的, false
。 : - / PHP和它的输入...
如果没有将strict参数设置为true
您应该永远不会调用in_array()
。 如果没有混合类型的数组,并且只检查具有相同类型的值,则in_array()
将按预期工作。 看这个例子:
$arrayWithStrings = ['Andreas', 'Philipp', 'Friedrich'];
var_dump(in_array('Gary', $arrayWithStrings)); // returns bool(false)
所以至少这可以按预期工作。 但在我看来,总是用严格的 true
调用in_array()
要容易得多。 (与“SQL注入问题”类似...只是总是使用PDO和预处理语句,所以你是安全的,即使它是一个没有可变参数的查询。你总是安全的。)
你绝对应该用严格的 true
调用in_array()
。 但是有一个缺点,我想提一下(尽管很明显)。 在调用in_array()
时,您必须使用正确的类型:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array('1', $arrayWithNumbers, true)); // returns bool(false)
但是当你知道比较数字时,你可以使用Type Casting:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array((int)'1', $arrayWithNumbers, true)); // returns bool(true)
// Comparing false with an empty array
var_dump(in_array(false, [[]])); // returns bool(true)
好吧,是的...只需使用严格设置为true
。 ;-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.