运行以下代码,可能会发现跟我们想象的有所差别,让我们一起研究下当PHP变量类型不一致时,变量比较为什么会产生这种奇葩结果。
echo 'abc' == 0 ? '相等' : '不相等';//相等
echo '1abc' == 1 ? '相等' : '不相等';//相等
echo 'abc1' == 1 ? '相等' : '不相等';//不相等
echo md5('240610708') == md5('QNKCDZO') ? '相等' : '不相等';//相等
echo "0x1e240"=="123456" ? '相等' : '不相等';//相等
PHP比较运算符
符号 | 示例 | 名称 | 描述 |
---|---|---|---|
== | $a == $b | 等于 | 类型转换为同一个类型后进行比较 |
=== | $a === $b | 全等 | 先比较类型,类型相同在进行值比较 |
!= 或 <> | $a != $b | 不等 | 如果类型转换后,值不相等 |
!== | $a !== $b | 不全等 | 如果类型或者值不相等返回true |
<=> | $a <=> $b | 类型转换后,结合比较运算符 | 如果a < b ,a == b,a > b ,分别输出-1 , 0 ,1 |
> | $a > $b | 大于 | a大于b,输入true |
>= | $a >= $b | 大于等于 | a大于或等于b,输入true |
< | $a < $b | 小于 | a小于b,输入true |
<= | $a <= $b | 小于等于 | a小于或等于b,输入true |
PHP变量类型自动转换规则
使用像“==”、“!=”这样不需要区分类型的比较运算符进行比较时成为松散比较,PHP会先把符号两侧变量转为统一类型。
这里对PHP松散比较符号“==“进行了梳理(T代表true F代码false)
TRUE | FALSE | 1 | 0 | “1” | “0” | NULL | array() | “” | |
---|---|---|---|---|---|---|---|---|---|
TRUE | T | F | T | F | T | F | F | F | F |
FALSE | F | T | F | T | F | T | T | T | T |
1 | T | F | T | F | T | F | F | F | F |
0 | F | T | F | T | F | T | T | F | T |
“1” | T | F | T | F | T | F | F | F | F |
“0” | F | T | F | T | F | T | F | F | F |
NULL | F | T | F | T | F | F | T | T | T |
array() | F | T | F | F | F | F | T | T | F |
“” | F | T | F | T | F | F | T | F | T |
PHP是按照什么转换的呢?
- int和string比较:string自动转为int
- int和float比较:int自动转为float
- 任何类型和bool比较:都会自动转为bool
- 任何类型和非空数组比较:
- 任何类型和null、空array比较:除了自身和false外,其余均为fasle
相信看到这里可以理解文章开头的前三个问题了,都是现将string转为了int,然后才进行的比较。
PHP强制类型转换
- string转int
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
- int转int
$item = (string)$var;
$item2 = strval($var);
- Hash比较:在进行比较运算时,如果字符串开头遇到0e这种字符串,就会将这种字符串解析为科学计数法。所以上面问题4变成了两个科学计数法数字比较,刚好都是0
- 十六进制转换:一个字符串是0x开头的时候,PHP会将此字符串解析成为十进制然后再进行比较,0x1240解析成为十进制就是123456,所以与int类型和string类型的123456比较都是相等。
PHP的弱类型确实使我们开发变得简单,但是用的时候还是要注意,以防发生上述问题。能用严格比较尽量用严格比较。