php中的数据类型的自动转换,对in_array函数的结果影响还是很大的。 以下内容测试於PHP7.2版本。
函数定义:
in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) : bool
Searches for needle in haystack using loose comparison unless strict is set.
Parameters
needle
The searched value.
Note:
If needle is a string, the comparison is done in a case-sensitive manner.
haystack
The array.
strict
If the third parameter strict is set to TRUE then the in_array() function will also check the types of the needle in the haystack.
看下needle下面的note:
If needle is a string, the comparison is done in a case-sensitive manner.
翻译过来就是:
如果 needle 是字符串,则比较是区分大小写的。
那么这个字符串到底是什么含义呢? "12", "12.0" 这种类型的是不是字符串呢?
is_string("12") // true
is_string("12.0") // true
如果使用函数is_string去判断, 上面都是正确的。
那我们看一下下面的几个结果:
in_array("012", [12, "a", "1"]) // true
in_array("12", [12, "a", "1"]) // true
in_array("12.0", [12, "a", "1"]) // true
in_array("12.0", [12.0, "a", "1"]) // true
上面的几个结果,都是true。
如果使用in_array时不使用strict模式,那么php会根据haystack中的value的类型去转换needle的类型, 以下几个判断在php中都是成立的:
"12" == 12
"01" == 1
"h1" == 0
上面的字符串和数值(int/float)比较, 类型会做转换。 但是字符串形式的数值在比较的时候, 也被做了自动转换(string=> int / float):
"01" == "1"
"1.2" == "1.20"
So, 在非strict模式下, in_array方法中的needle的string类型的区分大小写的字符串比较,不包含 int/float 形式的假字符串。而且, 这个字符串类型限制还不仅仅限于needle,也包括了haystack中的value的类型。
something else:
如果needle是boolean的false/true,会被转换为0/1, 如果是null会被转换为0, 比如:
in_array(false, [0, "a", "1"]) // true
in_array(true, ["c", "a", "1"]) //true
in_array(null, [0, "a", "1"]) //true
但是,
in_array(null, ["0", "a", "1"]) //false
WHY?
使用in_array时, 务必注意是否需要启用strict模式。