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?因为null转string时为空:
var_dump((int)null); //结果是: int(0)
var_dump((string)null); //结果是: string(0) ""
使用in_array时, 务必注意是否需要启用strict模式。
注意: 函数 array_search 存在同样的问题