PHP 运算符

运算符是程序做"运算"的符号——加减乘除、比较大小、判断真假。PHP 的运算符和 C/Java/JS 几乎一样,但有两个 PHP 特色需要特别注意:字符串连接用点 .(不是 +),以及弱类型比较的坑

1. 算术运算符

最常见的数学运算,和其他语言基本一致:

<?php
// 算术运算符
echo 7 + 3;    // 10  加
echo 7 - 3;    // 4   减
echo 7 * 3;    // 21  乘
echo 7 / 3;    // 2.333... 除(结果总是 float,除非整除)
echo 7 % 3;    // 1   取模(余数)
echo 7 ** 2;   // 49  乘方(PHP 5.6+)
echo intdiv(7, 3); // 2  整除(PHP 7+)

// 自增/自减
$i = 5;
$i++;          // $i 变 6(后置,先返回后加)
++$i;          // $i 变 7(前置,先加后返回)
$i--;          // $i 变 6
--$i;          // $i 变 5

注意 / 除法结果总是 float(即使整除),intdiv() 才是整除。** 是 PHP 5.6+ 加的乘方运算符。

2. 赋值与复合赋值

<?php
// 基本赋值
$x = 10;

// 复合赋值(运算符 + 赋值)
$x += 5;    // 等价于 $x = $x + 5
$x -= 3;    // 等价于 $x = $x - 3
$x *= 2;    // 等价于 $x = $x * 2
$x /= 4;    // 等价于 $x = $x / 4
$x %= 3;    // 等价于 $x = $x % 3
$x **= 2;   // 等价于 $x = $x ** 2
$x .= "abc"; // 等价于 $x = $x . "abc"(字符串拼接)

复合赋值(+=-= 等)是简写,等价于"自己运算后再赋值"。字符串连接也有对应的 .=

3. 比较运算符(重点!)

比较运算符返回 bool。PHP 有两套比较:==(弱相等,会自动转换类型)和 ===(全等,值和类型都必须相同)。

<?php
// 比较运算符:返回 bool
var_dump(3 == 3);    // true   等于(值)
var_dump(3 === 3);   // true   全等(值 + 类型)
var_dump(3 != 4);    // true   不等
var_dump(3 !== "3"); // true   非全等
var_dump(3 < 4);     // true   小于
var_dump(3 > 4);     // false  大于
var_dump(3 <= 3);    // true   小于等于
var_dump(3 >= 4);    // false  大于等于

// 弱类型比较(== 会自动转换,容易踩坑)
var_dump("3" == 3);      // true!
var_dump("abc" == 0);    // true!(PHP 8 前的行为)
var_dump(null == false); // true!

// 永远优先用 ===

核心铁律:永远优先用 ===== 在 PHP 里行为反直觉,是无数 bug 的根源。PHP 8 改善了部分行为("abc" == 0 不再为 true),但依然建议统一用 ===

4. 太空船运算符

PHP 7 引入了太空船(three-way comparison),一次性返回"小于/等于/大于"三种结果,主要用于排序:

<?php
// 太空船运算符 <=>(PHP 7+)
// 返回 -1 / 0 / 1,用于排序
echo 1 <=> 2;    // -1(左边小于右边)
echo 2 <=> 2;    //  0(相等)
echo 3 <=> 2;    //  1(左边大于右边)

// 适用所有可比较类型
echo "a" <=> "b"; // -1(字典序)
echo [1] <=> [2]; // -1

典型的排序回调:用 usort 配合太空船运算符,按数组元素的某个字段排序。这是 PHP 7+ 推荐写法,替代老的三目运算写法(具体代码见上方 cHigher 示例)。

5. 逻辑运算符

逻辑运算符处理 bool 值,主要有 &&(与)、||(或)、!(非)三种:

<?php
// 逻辑运算符
$a = true;
$b = false;

var_dump($a && $b);  // false  逻辑与(and)
var_dump($a || $b);  // true   逻辑或(or)
var_dump(!$b);       // true   逻辑非
var_dump($a and $b); // false  and(优先级低,少用)
var_dump($a or $b);  // true   or (优先级低,少用)
var_dump($a xor $b); // true   异或(只有一个为真)

// 短路求值(&& 和 ||)
$user = $config["user"] ?? "guest";
// ?? 是 null 合并运算符,等价于 isset 判断

// 典型短路:避免空指针
$len = isset($s) && strlen($s) > 0;

PHP 同时支持 and / or / xor 关键字,但优先级比 = 还低,容易出 bug,不推荐。日常用符号版本。

5.1 短路求值

&&|| 都是短路的——如果第一个操作数就能确定结果,第二个就不会求值。这个特性常用来防错:

6. 字符串连接运算符(PHP 特色!)

这是 PHP 区别于其他语言最显眼的地方:字符串拼接用点 .,不是加号 +。这是新手必踩的坑:

<?php
// 字符串连接:. (不是 +!)
$greeting = "你好" . ",世界";
echo $greeting;             // 你好,世界

// 复合赋值 .=
$name = "小";
$name .= "明";
echo $name;                 // 小明

// 重复 str_repeat
echo str_repeat("ab", 3);   // ababab

// ⚠️ 坑:用 + 拼接字符串会被转成数字相加
echo "3" + "4";             // 7(不是 "34"!)
echo "3" . "4";             // 34(这才是拼接)

原因:PHP 是弱类型,"3" + "4" 会把两个字符串转成数字相加,得到 7。要拼接字符串,必须用 .。这是 PHP 设计历史决定的,理解就好。

7. 三元、null 合并与 Elvis

这三个是 PHP 表达式灵活的关键,Web 开发几乎每天用:

<?php
// null 合并运算符 ??(PHP 7+)
$name = $_GET["name"] ?? "匿名";
// 等价于:
// $name = isset($_GET["name"]) ? $_GET["name"] : "匿名";

// 链式使用
$user = $data["user"] ?? $config["user"] ?? "guest";

// ??=(PHP 7.4+)null 合并赋值
$name ??= "默认值";   // 如果 $name 是 null 则赋值

// 三元运算符 ? :
$level = $score >= 60 ? "及格" : "不及格";

// PHP 8:更短的 ternary
$level = $score >= 60 ?: "不及格";
// 等价于 $level = $score >= 60 ? true : "不及格"

特别推荐 ??(null 合并):处理"可能未设置的变量"极其方便,是 isset 三目的简写。??=(null 合并赋值)用于"如果是 null 就赋默认值"。

8. 位运算符(了解)

位运算操作整数的二进制位,日常 Web 开发用得少,主要场景是权限位标记:

9. 运算符优先级(常见问题)

PHP 有几十个运算符,优先级从高到低大致是:自增自减 → 算术 → 字符串连接 → 比较 → 逻辑非 → 逻辑与 → 逻辑或 → 三目 → 赋值不确定就加括号,可读性比抠优先级重要。

常见坑:$a = $b = $c = 5 是连续赋值;$a && $b = $c 因为 && 优先级高于 =,实际等价于 ($a && $b) = $c 报错——遇到这种写括号。

小结

这一章你掌握了 PHP 全部常用运算符,以及两个核心陷阱:字符串拼接用 .永远用 === 严格比较。下一篇我们看控制流程——让程序能做判断、能循环。

← 上一篇 PHP 数据类型

下一篇 PHP 控制流程

✈️💬