PHP隐式类型转换
2018-08-05
PHP是一种弱类型的语言,不像C
语言或者go
语言等,必须在定义变量时就定义变量类型。在运算过程中,会根据运算符类型,对变量进行隐式类型转换。在类型隐式转换过程中,可能会产生很多不可思议的问题。
比较运算符
比较运算符主要有几下几种
例子 | 名称 | 结果 |
$a == $b | 等于 | TRUE,如果类型转换后 $a 等于 $b |
$a === $b | 全等 | TRUE,如果 $a 等于 $b,并且它们的类型也相同 |
$a != $b | 不等 | TRUE,如果类型转换后 $a 不等于 $b |
$a <> $b | 不等 | TRUE,如果类型转换后 $a 不等于 $b |
$a !== $b | 不全等 | TRUE,如果 $a 不等于 $b,或者它们的类型不同 |
$a < $b | 小与 | TRUE,如果 $a 严格小于 $b |
$a > $b | 大于 | TRUE,如果 $a 严格大于 $b |
$a <= $b | 小于等于 | TRUE,如果 $a 小于或者等于 $b |
$a >= $b | 大于等于 | TRUE,如果 $a 大于或者等于 $b |
$a <=> $b | 太空船运算符(组合比较符) | 当$a小于、等于、大于$b时 分别返回一个小于、等于、大于0的integer 值。 PHP7开始提供 |
$a ?? $b ?? $c | NULL 合并操作符 | 从左往右第一个存在且不为 NULL 的操作数。如果都没有定义且不为 NULL,则返回 NULL。PHP7开始提供 |
运算规则
这种类型的运算符,需要注意一下几点
- 比较数字和字符串,字符串转换为数值再进行比较
10 == '1e1'; // 10 == 10
- 两个纯数字字符串比较,字符串转换为数值进行比较
'001' == '1'; // 1 == 1
- 两个包含
e
或E
的字符串,字符串转换为数值进行比较
'001e1' == '1e1'; // 10 == 10
- 一个纯数字字符串,另一个包含
e
或E
的字符串,两者转换为数值进行比较
'0010' == '1e1'; // 10 == 10
- 包含字母的字符串,根据字符串ACSII码进行比较
'0010a' < '1e1'; // 48(0的ascii码) < 49(1的ascii码)
- 两个字符串比较,会将字符串转换为ASCII码进行比较
- 此规则也适用于 switch 语句
- 当用
===
或!==
进行比较时不进行类型转换
存在问题
因为在PHP中,对字符串比较存在隐式类型转换的问题,所以在一些程序对哈希值字符串进行校验时会存在绕过的问题
/*
'0e462097431906509019562988736854' == '0e830400451993494058024219903391'
=>
0 == 0
*/
md5('240610708') == md5('QNKCDZO');
同样以0e
开头的md5还有很多,可以参考另外一篇文章0e开头的md5总结记录。
References
[1]PHP比较运算符
[2]php运算时默认的类型转换
[3]开头为0的md5值总结