澳门新葡萄京官网注册用PHP中的 == 运算符进行字符串比较

最近在Greg Beaver’s的blog上发表的一篇新文章 comparing strings in PHP
with the ==
operator
中提及了PHP的 == 运算符在对字符串进行比较时值得注意的问题。

原文:https://www.fanhaobai.com/2016/07/functions-in-array.html

  在某些情况下,PHP会把类数值数据(如含有数字的字符串等)转换成数值处理,==
运算符就是其中之一。在使用 ==
运算符对两个字符串进行松散比较时,PHP会把类数值的字符串转换为数值进行比较,下面的实验证实了这个结论:
<?phpvar_dump('01' == 1);?>以上代码输出结果为:
bool(true)

在 PHP 项目开发过程中,in_array
函数你一定使用不少吧,那么你知道in_array(0, array('s'))返回什么吗?

  所以,在使用对字符串进行比较时,建议使用 ===
运算符对字符串进行严格的检查,或使用strcmp()等函数,从而避免可能产生的问题。PHP手册中的《PHP
类型比较表》对此也有详细说明。

对于上面这个问题,我想一般人都会觉得结果是 false,而实际结果应该是
true,不信可以运行代码就知道结果了。

  除此之外,常用的in_array()函数也存在弱类型的问题,见如下代码:

那么,为什么 PHP
会认为整型0会存在于数组array('s')中呢,很明显数组中只存在字符串s,而不存在整型0的呀?

<?phpvar_dump(in_array('01', array('1')));?>
以上代码输出结果为:
bool(true)

查阅手册

在 PHP官方手册
中查阅到in_array函数的说明,如下:

bool in_array ( mixed $needle , array $haystack [, bool $strict =
FALSE ] )

说明:在 haystack 中搜索 needle,如果没有设置 strict 则使用 宽松
的比较。如果第三个参数 strict 的值为 true,则 in_array 函数还会检查
needle 的 类型 是否和 haystack 中的相同。

in_array 函数存在第三个参数
strict,它用来标记函数在对两元素进行比较时是否采用 严格比较,类似 ==
和 === 区别,in_array 函数默认采用 宽松
比较,即不比较类型,只比较值是否相等。

  相信用过该函数进行安全性检查的PHP编程人员都知道这会产生怎么样的安全问题了吧?幸好in_array()函数为我们提供了第三个参数,把它设为
true 就可以打开in_array()函数的强制类型检查机制,如下代码所示:

分析原因

现在看来,之所以结果出现 true,是因为 in_array
函数没有使用第三个参数,而默认进行了 宽松 比较,即等同于
0 == 's' ? 的问题。

由于 PHP
是弱类型语言,在对两个不同类型的值进行操作(比较运算)时,会存在数据类型的
隐式转化

比较运算不同类型转化规则 如下表:

{% asset_img ftmDbIAmvincNjudJwK3N82_.png %}

可知,当两不同类型数值中含有数字类型,都会转化为数字类型进行比较。那么s转化为数字类型为0,所以0 == 0 ?判断为
true,这就是为什么in_array(0, array('s'))结果为 true 的原因。

<?php var_dump(in_array('01', array('1'), true)); ?>输出结果为:
bool(false)

思考

那么想要达到我们预期的效果,上述问题必须进行 严格
比较,可以使用in_array(0, array('s'), true),这也告诫 我们在使用
in_array
函数时,若不能预知待搜索值和数组元素的类型,建议将第三个参数设为
true,保证比较时进行严格比较,进而不会产生意外的结果。

  由于PHP是一种弱类型的语言,也就是说数据类型这个概念在PHP中被弱化。因而如果在编程时过分忽略数据类型(也是大部份PHP程序员的通病),会产生一些问题,甚至导致安全漏洞。最后,还是那句说得很烦很烦的话,对外来数据进行严格检查和过滤。

发表评论

电子邮件地址不会被公开。 必填项已用*标注