一、弱数据类型导致的缺陷
PHP是弱数据类型语言、因此,在进行 == 判断时,会存在一些隐患。
1、Hash 比较缺陷
如果 Hash 值以 0e 开头,当与数字比较时,就会被解析为 0 * 10ⁿ,会被判断与0相同。
解决方案:使用 === 进行全等判断
2、数字比较缺陷
PHP中,允许比较的最大值为 PHP_INT_MAX
,也就是9223372036854775807,如果超出这个范围,则比较时将可能得不到正确的结果。
<?php
declare(strict_types = 1);
$intOne = 92233720368547758072;
$intTwo = 92233720368547758073;
if ($intOne === $intTwo) {
echo '相等';
} else {
echo '不相等';
}
得到的结果是‘相等’,因为比较时超出了PHP最大范围,因此只比较到最大范围截止,出现了不理想的结果。所以比较时,注意限定要比较的数字允许最大范围。
3、类型自动转换缺陷
<?php
declare(strict_types = 1);
$a = 22;
$b = '22cd5';
echo $a == $b ? '相等' : '不相等';
得到的结果是相等。
第一种解决方案:使用 === 进行判断
第二种解决方案:在比较前,对需要比较的变量进行类型判断,接收参数时,也强制数据类型。
<?php
declare(strict_types = 1);
class Test
{
public function operate(int $firstNum, int $secondNum)
{
// 业务逻辑处理
}
}
利用PHP7的新特性严格模式,做强类型要求。
4、switch 比较缺陷
<?php
declare(strict_types = 1);
$type = '2sec';
switch ($type) {
case 1 :
echo 'this is 1';
break;
case 2 :
echo 'this is 2';
break;
default :
echo 'this is default';
break;
}
得到的结果是 ‘this is 2’, $type在比较时,被自动转换成其他了。
解决方案:在比较前对参数进行校验。
<?php
declare(strict_types = 1);
$type = '2sec';
if (!is_numeric($type) || !in_array($type, [1, 2])) {
echo '类型只能是1或者2,这里是错误抛出';
}
switch ($type) {
case 1 :
echo 'this is 1';
break;
case 2 :
echo 'this is 2';
break;
default :
echo 'this is default';
break;
}
5、数组比较缺陷
在使用 in_array
或者 array_search
时,第三个参数严格模式设置为true。
<?php
declare(strict_types = 1);
$type = '2sec';
// 没使用严格判断模式,得到的结果是合法
if (!in_array($type, [1, 2, 3])) {
echo '不合法';
} else {
echo '合法';
}
// 使用了严格模式判断,得到的结果是不合法
if (!in_array($type, [1, 2], true)) {
echo '不合法';
}