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 短路求值
&& 和 || 都是短路的——如果第一个操作数就能确定结果,第二个就不会求值。这个特性常用来防错:
- 检查字符串非空时,先用
isset再调用strlen— 第一个为 false 就跳过第二个,避免未定义变量错误。 isAdmin() || redirect("/login")— 不是管理员就跳转。
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 开发用得少,主要场景是权限位标记:
&按位与,|按位或,^按位异或,~按位非。<<左移,>>右移(相当于乘除 2 的幂)。- 典型用法:权限常量
const READ = 1; const WRITE = 2; const EXEC = 4;,用|组合、&检测。
9. 运算符优先级(常见问题)
PHP 有几十个运算符,优先级从高到低大致是:自增自减 → 算术 → 字符串连接 → 比较 → 逻辑非 → 逻辑与 → 逻辑或 → 三目 → 赋值。不确定就加括号,可读性比抠优先级重要。
常见坑:$a = $b = $c = 5 是连续赋值;$a && $b = $c 因为 && 优先级高于 =,实际等价于 ($a && $b) = $c 报错——遇到这种写括号。
小结
这一章你掌握了 PHP 全部常用运算符,以及两个核心陷阱:字符串拼接用 .、永远用 === 严格比较。下一篇我们看控制流程——让程序能做判断、能循环。
← 上一篇 PHP 数据类型
下一篇 PHP 控制流程 →