PHP中不同类型比较,php中的弱类型比较

关于等号

在大多数编程语言中,一个等号代表赋值,两个等号代表等于,php也是这样的,但php却还有一个三个等号。三个等号也代表相等,那么两个等号和三个等号之间有什么不同的呢。

在php中,使用两个等号来判断时,只需要两个变量的值相同即可返回true,否则返回false。而使用三个等号,则需要两个变量不仅要值相同,并且两个变量的类型也必须相同时才会返回true,否则返回false。举个简单的例子,a变量为数字1,b变量为字符‘1’,在php中,$a==$b就会返回一个true,而$a===$b就会返回false。那么这就形成了第一种弱类型,使用两个等号判断变量是否相同时时,只需要变量的值相同,变量类型却没有要求。

关于类型转换

php是一种若类型语言,所以在比较过程中,会对变量进行自动的类型转换。可以看看下面的例子。echo "0=='':";

var_dump(0=='');

echo "
null==false:";

var_dump(null==false);

echo "
1='1abc':";

var_dump(1=='1abc');

echo "
0='abcdefg':";

var_dump(0=='abcdefg');

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-10-23%20%E4%B8%8B%E5%8D%882.03.50.png

可以看到输出结果都为true。可见,php在进行字符串与数字比较时,会强制把字符串转换为数字,而转换时会截取到第一个不是数字的字符前,再见上双等号的缘故。所以1与’1abc’是相等的而0与’abcdefg’是相等的。而且,在php中如果遇到了0e数字的形式会当成科学计数法来处理,所以所有0e数字形式的字符串在进行比较的时候都会被当成0.这也就是在很多ctf中都有出现的“md5碰撞”实质就是两个md5值都是0e数字形式的字符串比较时是相等的。

关于函数

php中有很多存在有弱类型问题的函数。

md5()

php中可以使用md5函数来加密一个字符串,所以md5函数需要传入一个字符串,但是如果我们给md5函数中传入一个数组,此时md5不会报错,但会返回一个null,此时两个null比较就是相等的了。测试:$a=array('abc','def');

$b=array('hij','klm');

$c=array('hhh'=>'aaa');

var_dump(md5($a)==md5($b));

var_dump(md5($a)==md5($c));

运行结果:

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-10-23%20%E4%B8%8B%E5%8D%882.36.20.png

intval()

intval()函数可以将字符串转化为int,但就像在前面类型转换时所看到的,intval()函数在转换时,也是只截取到第一个不为数字的字符。

strcmp()

strcmp()函数时php中判断字符串是否相等的函数,它实现的方法是通过将需要比较的变量传唤成ascii值,之后相减看结果的正负。如果相等的话,就会返回0,不想等就会返回1或-1。然而当我们将一个参数改为数组,此时,strcmp()不会报错但会返回null,然后null与0在使用两个等号比较时又是相等的,这就会存在一个绕过啦,测试:$a='test';

$b=array('heiheihei');

var_dump(strcmp($a, $b));

if(strcmp($a, $b)==0){

echo "
bypass it";

}

运行结果

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-10-23%20%E4%B8%8B%E5%8D%883.04.20.png

in_array()

in_array()在手册中的定义为:bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )第一个参数是索要查找的变量,第二个参数是一个目标数组,第三个参数默认为false,如果没有传入第三个参数,则其值为false,也就是说不会要求类型一致。如果传入了一个true,则会寻找数组中与变量值相同且类型一致的元素。换句话说,这个函数实现的方法就是遍历整个数组,然后使用两个等号去对每一个元素和传入的变量进行比较,如果有返回true认为变量在这个数组中是存在的。那么我们这里就存在两个等号比较时会出现的问题,比如说:$a='222test';

$b=array(111,222,333);

var_dump(in_array($a,$b));

运行结果

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-10-23%20%E4%B8%8B%E5%8D%883.17.41.png

switch()

php中在执行switch($case)语句时,如果case的类型为int,则会对传入的值进行类型转换,那么此时就涉及到前面所说的类型转换问题了。$a='3test';

switch ($a) {

case 1:

echo "this is 1";

break;

case 2:

echo "this is 2";

break;

case 3:

echo "this is 3";

break;

default:

echo "other";

break;

}

运行结果

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202016-10-23%20%E4%B8%8B%E5%8D%883.25.39.png

总结

php是一种弱类型语言,这种弱类型与语言方式虽然会带来一些便捷,但也会存在一些安全问题。所以在进行开发时要尽量避免使用不安全的弱类型比较并对参数进行严格的限制,不要让用户可控的参数直接进入到危险函数中。最后附一张php中弱类型的松散比较表格:

ee2213e7e62e670617da34fbb1189992.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值