执行以上代码,0和字符串是可以匹配成功的。
原因是在in_array,如果比较的类型不匹配,并且第一个参数是0,它会返回true(不正确)。
查手册:If the third parameter strict is set to TRUE then the in_array() function will also check the of theneedle in thehaystack.
加上类型比较后返回false(正确)
经查阅相关资料如下:
1.情况一
$test = 'a';$array = array('a', 'b', 'c');if (in_array($test, $array)) {echo 'in array';} else { echo 'no';}//output: in array
2.情况二
$test = 'other value';$array = array('a', 'b', 'c');if (in_array($test, $array)) {echo 'in array';} else { echo 'no';}//output: no
------------------------ 看似一切都正常的分割线 -----------------------
3.情况三
$test = 0;$array = array('a', 'b', 'c');if (in_array($test, $array)) { echo 'in array';} else { echo 'no';}//output: in array
难以置信,这不坑爹吗,0不在列表中,但是这个函数返回true。这个函数很常用,所以当某些巧合出现后,就会导致不可预料的错误。
一开始我猜测in_array函数除了在values中寻找,还会去寻找keys,后来发现不是这样的。
4.情况四
$test = '0';$array = array('a', 'b', 'c');if (in_array($test, $array)) { echo 'in array';} else { echo 'no';}//output: no
是不是很有意思
5.原来是因为:
var_dump(0 == "a"); // 0 == 0 -> truevar_dump("1" == "01"); // 1 == 1 -> truevar_dump("10" == "1e1"); // 10 == 10 -> truevar_dump(100 == "1e2"); // 100 == 100 -> true
php比较数字和字符串时,会尝试将字符串转换为数字再进行比较。 例子中的 'a', 'b', 'c' 转成数字都是0,所以和0相等,in_array就返回了true。
6.如何避免
PHP的类型戏法是把双刃剑,有时候很爽,有时候很贱。
所以当in_array的needle与array中的值类型是否相同还不确定时,最好设置in_array函数的第三个参数 strict = true,这样在检查的时候会检查类型,数字与字符串就不会偷偷相等,也就避免类似这种问题。
$test = 0;$array = array('a', 'b', 'c');if (in_array($test, $array, true)) { echo 'in array';} else { echo 'no';}//output: no
原文链接: