主题
比较运算符
比较运算符用来判断两个值的关系,结果是布尔值 true 或 false。条件分支、循环都靠它。
php
<?php
$age = 18;
var_dump($age >= 18); // true
var_dump($age === "18"); // false,类型不同
var_dump($age == "18"); // true,宽松比较会转换类型一览
| 运算符 | 名称 | 为 true 的情况 |
|---|---|---|
== | 相等 | 转换类型后值相等 |
=== | 全等 | 值和类型都相同 |
!= / <> | 不等 | 转换类型后值不相等 |
!== | 不全等 | 值或类型有一个不同 |
< | 小于 | 左边更小 |
> | 大于 | 左边更大 |
<= | 小于等于 | 左边较小或相等 |
>= | 大于等于 | 左边较大或相等 |
<=> | 太空船 | 左小返回 -1,相等 0,左大 1 |
日常优先用 === / !==,只有确实需要「自动转类型再比」时才用 ==。
宽松 == 和严格 ===
== 会先尝试把两边转成同一类型,再比大小;=== 类型不同直接 false。
php
<?php
var_dump(0 == "0"); // true
var_dump(0 === "0"); // false
var_dump(1 == true); // true
var_dump(1 === true); // false
var_dump(null == false); // true
var_dump(null === false); // false!= 对应 ==,!== 对应 ===。<> 和 != 完全一样,现在更常见的是 !=。
PHP 8 里几个容易踩的变化
PHP 8 收紧了「数字和字符串」的宽松比较,不再把随便一个字符串当成 0:
php
<?php
var_dump(0 == "0"); // true,数字字符串仍可比较
var_dump(0 == "0.0"); // true
var_dump(0 == ""); // false(PHP 7 曾是 true)
var_dump(0 == "foo"); // false(PHP 7 曾是 true)
var_dump(0 == "0foo"); // false(PHP 7 曾是 true)即便如此,== 仍然有不少「看起来古怪」的结果。比较两个值是否真的相同,用 === 最省心。
大小比较
数字按数值比,字符串默认按字节(字典序)比:
php
<?php
var_dump(10 > 3); // true
var_dump(10 <= 10); // true
var_dump("b" > "a"); // true
var_dump("10" > "9"); // false,字符串是 "1" 和 "9" 比
var_dump((int) "10" > (int) "9"); // true,先转数字一边是数字、一边是数字字符串时,会按数字比:
php
<?php
var_dump(10 > "9"); // true
var_dump(10 > "9abc"); // PHP 8:按字符串比较,结果取决于具体规则,不要这么写需要按数值比大小,就先转成 int / float,不要混用类型。
太空船运算符 <=>
一次比较给出三种结果,适合排序回调:
php
<?php
echo 1 <=> 2, "\n"; // -1
echo 1 <=> 1, "\n"; // 0
echo 2 <=> 1, "\n"; // 1
$nums = [3, 1, 2];
usort($nums, fn(int $a, int $b): int => $a <=> $b);
print_r($nums); // 1, 2, 3它遵循和 < / == / > 相同的比较规则。对象、数组也能比,初学先用于数字和字符串即可。
浮点数不要直接 ==
二进制浮点有精度误差:
php
<?php
var_dump(0.1 + 0.2 == 0.3); // false
var_dump(0.1 + 0.2); // 0.30000000000000004比浮点是否接近,用误差范围,或 abs($a - $b) < 0.00001。PHP 也提供 fdiv() 等函数,但「金额」更适合用整数分来存,不要用 float 表示钱。
常见对照
把下面印出来看一遍,比背口诀有用:
php
<?php
var_dump(false == 0);
var_dump(false === 0);
var_dump(false == "");
var_dump(false == []);
var_dump(null == false);
var_dump(null == "");
var_dump("0" == false);
var_dump("0" === false);
var_dump("0" == 0);记忆要点:
false、0、0.0、"0"、""、[]、null在宽松比较里经常互相「相等」===把它们全部区分开- 判断「有没有这个值」时,结合
isset()/empty()/=== null,不要只靠== false,详见 内置函数
和赋值、逻辑一起用
比较的优先级高于赋值、低于算术:
php
<?php
$n = 3;
var_dump($n + 1 > 3); // true,先算 3 + 1多个条件要用 逻辑运算符 连接:
php
<?php
$age = 20;
$hasId = true;
var_dump($age >= 18 && $hasId === true);写 if ($a = 1) 是赋值不是比较,见 赋值运算符。
书写建议
- 默认写
===/!== - 和
0、""、null、false比较时尤其不要用== - 用户输入是字符串
"18",要当数字比就先(int) $age,再和整数比 - 复杂条件拆成中间变量:
$isAdult = $age >= 18;,if里会好读很多
练习
- 对
0、"0"、false、null两两使用==和===,把var_dump结果记下来。 $score = 75,用比较运算符判断是否及格(>= 60)、是否优秀(>= 90)。- 解释为什么
"10" > "9"是false,并改成按数值比较。 - 用
<=>比较8和10,输出-1/0/1中的哪一个。