弱类型
**PHP属于弱类型语言,可能有人对此定义感到陌生,先通过例子简单描述一下弱类型语言和强类型语言。 **
强类型:不同类型的数值做比较或拼接时不会转型,会报错。
弱类型:不同类型的数值做比较或拼接时会自动发生转型。
PHP的变量定义不需要指明类型,该变量的类型是由传递的值决定的。
<?php
$a=123; #数字,整型
var_dump($a);
echo "</br>";
$a="123"; #字符串
var_dump($a);
echo "</br>";
$a=False; #布尔型
var_dump($a);
?>
对于强弱类型有不同的判断标准,这里从类型转换的角度看,PHP是会自动转型的弱类型语言。语法变得灵活了,但却容易引起歧义。
数值拼接转型
先用两个不同类型的变量拼接起来看看会发生什么:
<?php
$a=123;
var_dump($a); #var_dump() 输出变量的类型(长度)及信息
echo "</br>";
$b="abc";
var_dump($b);
echo "</br>";
$c=$a.$b;
var_dump($c);
?>
可见整型的$a与字符型的$b拼接后的新变量为字符型。
有很多有趣的组合可以尝试一下,这里可见,尽管两个变量类型相同,但还是会发生转型:
<?php
$a=False;
$b=True;
var_dump($a);
echo "</br>";
var_dump($b);
echo "</br>";
$c=$a.$b;
var_dump($c);
?>
我经过多次的拼接测试,得出自己的结论:
$整型 + $布尔型 => $整型
$字符型 + $布尔型 => $字符串
$整型 + $字符型 => $字符串
再观察规律可得:
布尔型False转型为NULL(字符串),布尔型True转型为1(字符串),再由上面最后一条式子的规律进行拼接转型。
强制类型转换
单独的一个变量,如果给它传递一个整型数值,它的类型就变成了整型。如果它跟另一个变量拼接就有可能会转型,我们也可以强行让它发生定向转型。
PHP提供了转型方法:
– (int)($args) #转换成整型
– (string)($args) #转换成字符串
– (bool)($args) #转换成布尔型
– (float)($args)
– (double)($args) #转换成浮点型
如果是”123″(字符串)转型成123(整型)这样的形式就很容易理解,但像”abc”(字符串)这样的怎么能转换成整型呢?
字符串转换成整型
先来运行实例深刻印象:
<?php
$a="abc"; #纯字符
$b="abc123"; #字符在前,数字在后
$c="123abc"; #数字在前,字符在后
var_dump((int)($a));
echo "</br>";
var_dump((int)($b));
echo "</br>";
var_dump((int)($c));
?>
**string类型转换成整型,从字符串的左边开始截取至第一个非整型值(包括小数点和其后可能紧跟的整型值),然后就输出截取到的整型值。NULL则输出0。 **
字符串转换成浮点型
- 一般情况,参考整型的处理机制(能截取第一个紧跟数字的小数点及紧跟小数点的整型值,但第二个小数点往后则不截取)
- 若字符串中存在e或E,则处理机制与上式的小数点一样,计算方法为次方。
强制转换成布尔型
- 整型0转换成False
- 浮点型0.0转换成False
- 空白字符串
- NULL
- 其余均转换成True
关于浮点型转换
- 浮点型转换成整型,小数点后的值均舍弃(不考虑四舍五入)
转型后的数值比较
**PHP有两种比较符号:’==’和’===” **
‘==’:先将两边变量转换成同一类型,然后比较数值是否相同
‘===’:不会转型,比较类型及数值是否都相同
关于’===’比较是没有转型的,对数值比较最为严格。’==’仅比较数值,更为灵活。
<?php
$a=123;
$b="123";
var_dump($a==$b);
echo "</br>";
var_dump($a===$b);
?>
**对于比较数值内容而言,’==’比较方便。不过PHP主要应用在web方面,如果运用在用户登陆认证等页面,则存在很大风险。 **
下面这些看起来毫不相关的值,其判断结果均为True。
<?php
var_dump("123'or 1=1"==123);
var_dump("0e78219763"=="0e5555");
var_dump("a'or 1=1"==0);
?>
结尾
危害方面的话,弱类型的PHP类型转换在进行’==’对比时有时会出现意料之外的结果,从安全角度考虑,我们需要改用’===’进行数据的比较。前提需要注意表单的类型均为string,尽管是纯数字的比较,也要设置好后端的验证变量为string型。
另外,ctf比赛中常见PHP弱类型比较,这方面需要多练习。