Menu

PHP 运算符:算术、逻辑、字符串运算符等

PHP 运算符对值进行运算:+、-、*、/、%、** 用于算术,=、+=、.=、??= 用于赋值,&&、||、! 和 xor 用于逻辑,. 用于连接字符串,==、===、<=> 用于比较,++、-- 用于自增自减。本文用可运行示例逐组讲解,还有 and 与 && 的优先级陷阱。

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

运算符接收一个或多个值,并产生一个新值:$a + $b 做加法,$a . $b 连接字符串,$a && $b 是逻辑与,$a === $b 做比较,$i++ 做自增。

除非两个整数能整除,否则 / 返回浮点数:17 / 5 是 3.4,10 / 5 是整数 2。只想要整数部分时,使用 intdiv()。舍入的内容见数学函数页面。

算术运算符

运算符名称示例结果
+加法7 + 29
-减法7 - 25
*乘法7 * 214
/除法7 / 23.5
%取模(余数)7 % 21
**幂7 ** 249
-$a取反-7-7

取模适合用来处理“每隔 N 个元素”和判断奇偶。它的结果符号与左边的操作数相同,除以零会抛出一个可以捕获的错误:

赋值运算符

= 存储一个值。每个算术运算符和字符串运算符都有对应的组合形式,可以直接更新变量。

??= 属于 null 合并运算符一族。只有当变量未设置或为 null 时,它才会赋值。

自增和自减:++ 和 --

$i++ 先返回当前值,再加 1。++$i 先加 1,再返回新值。只有在同一个表达式中使用它的结果时,两者的区别才会显现。

很多程序就是用这个字母技巧来生成电子表格的列名(A、B …… Z、AA)。

逻辑运算符:&&、||、! 和 xor

运算符何时为真
$a && $b两者都为真
$a || $b至少一个为真
!$a$a 为假
$a xor $b恰好一个为真
$a and $b、$a or $b与 && 和 || 相同,但优先级更低

&& 和 || 会短路:当左边已经决定了结果时,右边不会被求值。正因如此,isset($user) && $user->isAdmin() 才是安全的。

and 与 &&:优先级陷阱

and 和 or 的结合力比 = 弱,所以在赋值语句中,它们在值被存储之后才生效。这是一个经典 bug:

低优先级只在一种惯用写法中有用:$file = fopen($path, 'r') or die('Cannot open');,这里你正是希望赋值先执行。其他地方一律使用 && 和 ||。

字符串运算符:. 和 .=

PHP 有两个字符串运算符:. 连接两个字符串("Grace" . " " . "Hopper"),.= 把内容追加到变量末尾($html .= "<li>")。+ 从不连接字符串:"3" + "4" 是数字 7,而 "3" . "4" 是字符串 "34"。插值和引号的用法见字符串页面。

比较运算符和太空船运算符 <=>

== 先转换类型再比较,=== 还会检查类型,<=> 返回 -1、0 或 1,这正是排序回调所需要的。详细说明和完整的松散比较表见比较运算符页面。

数组运算符

数组上的 + 是并集:左边数组的键优先,右边数组只补充左边缺少的键。以为它会追加元素的人常常会被吓一跳。== 检查键值对是否相同,=== 还要求顺序和类型都相同。

要把一个列表追加到另一个列表后面,使用 array_merge() 或展开语法 [...$a, ...$b]。

运算符优先级

当一个表达式混用多个运算符时,PHP 会按固定的顺序执行它们。下面是最容易出错的几种,以及 PHP 8.3 的输出:

echo 2 + 3 * 4;        // 14: * before +
echo (2 + 3) * 4;      // 20
echo 2 ** 3 ** 2;      // 512: right to left, 2 ** 9
echo -2 ** 2;          // -4: ** before unary minus
echo "Sum: " . 2 + 3;  // Sum: 5, since PHP 8 + runs before .

拿不准时就加括号。括号没有任何代价,下一个读这行代码的人也不必去记优先级表。

常见问题

PHP 中 and 和 && 有什么区别?

两者都是逻辑与,但 and 的优先级比 = 低。所以 $x = true and false; 把 true 存进 $x(赋值先执行),而 $x = true && false; 存的是 false。在表达式中使用 && 和 ||,不要在赋值语句里用 and/or。

PHP 中 % 是做什么的?

% 是取模运算符:返回整数除法的余数,所以 10 % 3 是 1。结果的符号与左操作数相同(-7 % 3 是 -1)。浮点数请用 fmod(),而 % 0 会抛出 DivisionByZeroError。

PHP 中怎么计算一个数的几次方?

使用 ** 运算符:2 ** 10 是 1024。它是右结合的,所以 2 ** 3 ** 2 就是 2 ** 9 = 512;它的优先级也比一元负号高,所以 -2 ** 2 是 -4。函数 pow(2, 10) 的作用相同。

PHP 中 $i++ 和 ++$i 有什么区别?

两者都给 $i 加 1。$i++(后置自增)先返回旧值再加 1;++$i(前置自增)先加 1 再返回新值。单独写成一行时(比如 for 循环的步进部分),两者没有区别。

Coddy 编程语言插图

和 Coddy 一起学编程

开始