解决方案(简要):
始终将in_array()
与第三个参数strict true
一起使用:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue, true));
var_dump(in_array(0, $arrayWithNull, true));
var_dump(in_array(true, [-1], true));
如果您在使用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()
时,默认值为... 是的,false
。:-/ PHP及其类型系统...
后果是,您真的永远不应该在没有将strict参数设置为true
的情况下调用in_array()
函数。当您没有混合类型的数组并且只检查具有相同类型的值时,in_array()
就如预期工作。请参考以下示例:
$arrayWithStrings = ['Andreas', 'Philipp', 'Friedrich'];
var_dump(in_array('Gary', $arrayWithStrings));
所以至少这个功能是按照预期工作的。但在我看来,只需始终使用true
strict 调用 in_array()
更容易。 (类似于“SQL注入问题”...始终使用PDO和准备好的语句,以便您安全,即使它是一个没有变量参数的查询。那时您总是安全的。)
不过要小心
您肯定应该使用true
strict调用in_array()
。但是也有一个缺点,我想提一下(即使这是显而易见的)。然后您在调用in_array()
时必须确保使用正确的类型:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array('1', $arrayWithNumbers, true)); // returns bool(false)
但是当你知道要比较数字时,你可以使用类型转换:
$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)
嗯,是的...只需将 strict 设置为true
即可。 ;-)