Menu

PHP 比较运算符:== 与 === 以及 <=>

PHP 用 ==(类型转换后相等)、===(值相等且类型相同)、!= 和 !==、< > <= >= 以及太空船运算符 <=> 比较值。本文讲解 == 什么时候会转换类型、PHP 8 改了什么,并在一张表里列出所有松散比较和严格比较的结果。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

== 检查两个值在被 PHP 转换成同一种类型后是否相等。=== 检查它们是否相等,并且类型相同。所以 1 == "1" 是 true,而 1 === "1" 是 false。

大多数比较相关的 bug 都来自 == 做了你没料到的类型转换。比较好的默认做法是使用 === 和 !==,只有在确定需要类型转换时才改用 ==。

PHP 的所有比较运算符

运算符名称何时为真
$a == $b等于类型转换后相等
$a === $b全等相等且类型相同
$a != $b、$a <> $b不等于类型转换后不相等
$a !== $b不全等不相等,或类型不同
$a < $b、$a > $b小于,大于
$a <= $b、$a >= $b小于等于,大于等于
$a <=> $b太空船返回 -1、0 或 1

松散比较和严格比较对照表

这张表的每个格子都由 PHP 8.3 计算得出。在 == 和 === 之间切换,点一下格子就能看到对应的表达式。== 的表格在 null、""、"0" 和 [] 这几行里充满了意外;=== 的表格则只有对角线为真。

松散比较(==)和严格比较(===)
Point at or tap a cell to read it as PHP.
$a == $btruefalse10-1"1""0"""null[]"php""10""1e1"
true
false
1
0
-1
"1"
"0"
""
null
[]
"php"
"10"
"1e1"
Every cell computed by PHP 8.3.19.

== 如何比较不同类型的值

下面是 PHP 8 遵循的规则,按实际中的重要程度排列:

  1. 两个数字字符串按数字比较:"10" == "1e1" 和 "1" == "01" 都是 true。
  2. 数字和数字字符串:字符串会转换成数字。100 == "1e2" 是 true。
  3. 数字和非数字字符串:从 PHP 8 开始,数字会转换成字符串,然后按字符串比较。0 == "a" 是 false(在 PHP 7 中是 true)。
  4. 任意值和布尔值:两边都转换成布尔值。"a" == true 和 [] == false 都是 true。
  5. null 和字符串:null 会变成 "",所以 null == "" 是 true,但 null == "0" 是 false。和其他任何类型比较时,null 都按 false 来比较。
  6. 两个数组:拥有相同的键值对时相等。

最后一行说明了为什么用 null 做大小比较通常没有意义:null 变成 false,-1 变成 true,而 false < true。

不等于:!= 与 !==

!= 和 <> 是同一个运算符,!== 是它的严格版本。对于 strpos 这类会返回 0 或 false 的函数,两者的区别最重要:

0 != false 是 false,因为 0 会转换成 false。0 !== false 是 true,因为整数不是布尔值。array_search 以及不带严格标志的 in_array 也有同样的陷阱。

比较字符串

< 和 > 按字节比较字符串(对于普通 ASCII 字符就是按字母顺序)。如果两个字符串都是数字字符串,就按数字比较。要忽略大小写或按“自然”顺序比较,请使用这些函数:

太空船运算符 <=>

$a <=> $b 在 $a 较小时返回 -1,相等时返回 0,$a 较大时返回 1。它使用和 <、== 相同的规则,是编写排序回调最简短的方式。

用 <=> 比较两个数组时会逐个元素比较,回调正是靠这一点先按年龄、再按名字排序的。更多排序方法见数组排序页面。

常见错误:用 == 比较浮点数

浮点数以二进制存储,所以很多十进制数只是近似值。0.1 + 0.2 并不完全等于 0.3,而 == 能看出这个差别。

处理金额时,请把以分为单位的整数存起来,再用 === 比较。

常见问题

PHP 中 == 和 === 有什么区别?

== 先把两边转换成同一种类型再比较,所以 1 == "1" 是 true。=== 只有在值相等且类型相同时才为真,所以 1 === "1" 是 false。除非你需要类型转换,否则请使用 ===。

PHP 中 0 == "a" 是 true 吗?

从 PHP 8 开始不是了。当数字和非数字字符串比较时,PHP 8 会把它们当作字符串比较,所以 0 == "a" 是 false。在 PHP 7 中,字符串会被转换成 0,结果是 true。

PHP 中 != 和 !== 有什么区别?

!=(以及它的别名 <>)是 == 的反面:值在类型转换后相等时它为假。!== 是 === 的反面:值不同或类型不同时它为真,所以 0 !== false 是 true,而 0 != false 是 false。

PHP 中怎么比较两个浮点数?

不要对浮点运算的结果使用 ==:0.1 + 0.2 == 0.3 是 false。应该用一个很小的容差来比较它们的差值:abs($a - $b) < PHP_FLOAT_EPSILON,或者把两者都四舍五入到你关心的精度。

Coddy 编程语言插图

和 Coddy 一起学编程

开始