浅谈PHP类型转换机制

弱类型

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弱类型比较,这方面需要多练习。

发表评论

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

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据