PHP 运算符
Arithmetic, assignment, comparison, logic, bitwise, plus PHP-specific <=> and ??.
Key Points`==` compares loosely, `===` compares type too, and `.` concatenates instead of adding.
算术运算符
PHP
<?php
echo 7 + 3, " ", 7 - 3, " ", 7 * 3, " ", 7 / 2, " ", 7 % 3, "\n";
echo intdiv(7, 2), " ", 2 ** 10, "\n";
// 取模结果符号跟被除数走
echo -7 % 3, " ", 7 % -3, "\n";
// 字符串拼接
echo "a" . 1 . 2, "\n";Output
10 4 21 3.5 1
3 1024
-1 1
a127 / 2 yields 3.5. PHP's / returns int when evenly divisible, float otherwise. Use intdiv() for integer division; casting rounds toward zero.赋值运算符
PHP
<?php
$x = 10;
$x += 5; echo $x, "\n"; // 15
$x -= 3; echo $x, "\n"; // 12
$x *= 2; echo $x, "\n"; // 24
$x /= 4; echo $x, "\n"; // 6
$x %= 4; echo $x, "\n"; // 2
$x **= 3; echo $x, "\n"; // 8
$s = "a";
$s .= "b";
$s .= "c";
echo $s, "\n"; // abc
$arr = [1];
$arr[] = 2;
$arr[] = 3;
echo implode(",", $arr), "\n";Output
15
12
24
6
2
8
abc
1,2,3比较运算符
| Operator | Name | Example | Result |
|---|---|---|---|
| == | 等于(松散) | 10 == "10" | true |
| === | 全等 | 10 === "10" | false |
| != | 不等 | 10 != "10" | false |
| <> | 不等(旧写法) | 10 <> 11 | true |
| <=> | 飞船(三向比较) | 1 <=> 2 | -1 |
| ?? | 空合并 | null ?? "x" | x |
PHP
<?php
var_dump(7 <=> 3, 3 <=> 3, 3 <=> 7);
// 空合并:左边为 null 或未定义时取右边
$name = null;
echo $name ?? "默认名", "\n";
// Elvis:左边为假值时取右边("" 0 "0" null [] 都算假)
echo "" ?: "空字符串", "\n";
echo "0" ?: "零", "\n";Output
int(1)
int(0)
int(-1)
默认名
空字符串
零"0" 是假值,所以 "0" ?: "零" 返回 "零"。这是 PHP 最反直觉的一条:非空字符串居然为假。判断「用户填了没有」不能用 ?:,要用 !== '' 或 isset()。逻辑运算符
PHP
<?php
$a = true;
$b = false;
var_dump($a && $b);
var_dump($a || $b);
var_dump(!$a);
var_dump($a and $b); // 优先级低于 =
var_dump($a xor $b);
// 短路
function sideEffect() {
echo "被调用了\n";
return true;
}
var_dump(false && sideEffect());
var_dump(true || sideEffect());Output
bool(false)
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)&& and and differ in precedence: = binds tighter than and, so $x = true and false assigns true to $x. Always use && / ||.
位运算符
PHP
<?php
echo 6 & 3, "\n"; // 110 & 011 = 010
echo 6 | 3, "\n"; // 110 | 011 = 111
echo 6 ^ 3, "\n"; // 110 ^ 011 = 101
echo ~6, "\n"; // 取反
echo 1 << 4, "\n"; // 左移 = 乘 2^4
echo 256 >> 4, "\n"; // 右移 = 除 2^4Output
2
7
5
-7
16
16The classic use is permission bits: 1 << n for permission n, & to test, | to grant, ^ to revoke.
PHP
<?php
const READ = 1 << 0; // 1
const WRITE = 1 << 1; // 2
const EXECUTE = 1 << 2; // 4
$perm = READ | EXECUTE;
echo $perm, "\n"; // 5
var_dump((bool)($perm & READ)); // true
var_dump((bool)($perm & WRITE)); // false
$perm |= WRITE;
echo $perm, "\n"; // 7
$perm &= ~EXECUTE;
echo $perm, "\n"; // 3Output
5
bool(true)
bool(false)
7
3运算符优先级
No need to memorise the whole table — just the dangerous ones.
.has the same precedence as+-—1 . 2 + 3is(1 . 2) + 3!binds tighter than&&but looser than==andorxorbind looser than=??is right-associative
When unsure, add parentheses. They cost nothing; a precedence bug costs hours.
算术运算符
PHP
<?php
echo 7 + 3, " ", 7 - 3, " ", 7 * 3, " ", 7 / 2, " ", 7 % 3, "\n";
echo intdiv(7, 2), " ", 2 ** 10, "\n";
// 取模结果符号跟被除数走
echo -7 % 3, " ", 7 % -3, "\n";
// 字符串拼接
echo "a" . 1 . 2, "\n";Output
10 4 21 3.5 1
3 1024
-1 1
a127 / 2 得 3.5。PHP 的 / 在能整除时返回 int(10 / 2 是 int(5)),除不尽才返回 float。要强制整除用 intdiv(),别指望 (int) 强转——负数方向不同。赋值运算符
PHP
<?php
$x = 10;
$x += 5; echo $x, "\n"; // 15
$x -= 3; echo $x, "\n"; // 12
$x *= 2; echo $x, "\n"; // 24
$x /= 4; echo $x, "\n"; // 6
$x %= 4; echo $x, "\n"; // 2
$x **= 3; echo $x, "\n"; // 8
$s = "a";
$s .= "b";
$s .= "c";
echo $s, "\n"; // abc
$arr = [1];
$arr[] = 2;
$arr[] = 3;
echo implode(",", $arr), "\n";Output
15
12
24
6
2
8
abc
1,2,3比较运算符
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
| == | 等于(松散) | 10 == "10" | true |
| === | 全等 | 10 === "10" | false |
| != | 不等 | 10 != "10" | false |
| <> | 不等(旧写法) | 10 <> 11 | true |
| <=> | 飞船(三向比较) | 1 <=> 2 | -1 |
| ?? | 空合并 | null ?? "x" | x |
PHP
<?php
var_dump(7 <=> 3, 3 <=> 3, 3 <=> 7);
// 空合并:左边为 null 或未定义时取右边
$name = null;
echo $name ?? "默认名", "\n";
// Elvis:左边为假值时取右边("" 0 "0" null [] 都算假)
echo "" ?: "空字符串", "\n";
echo "0" ?: "零", "\n";Output
int(1)
int(0)
int(-1)
默认名
空字符串
零"0" is falsy, so "0" ?: "零" yields "零". The most counter-intuitive rule in PHP — never use ?: to test whether a field was filled.逻辑运算符
PHP
<?php
$a = true;
$b = false;
var_dump($a && $b);
var_dump($a || $b);
var_dump(!$a);
var_dump($a and $b); // 优先级低于 =
var_dump($a xor $b);
// 短路
function sideEffect() {
echo "被调用了\n";
return true;
}
var_dump(false && sideEffect());
var_dump(true || sideEffect());Output
bool(false)
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)&& 和 and 结果一样但优先级不同:= 高于 and,所以 $x = true and false 是 ($x = true) and false,$x 为 true。**写代码一律用 && / ||**。
位运算符
PHP
<?php
echo 6 & 3, "\n"; // 110 & 011 = 010
echo 6 | 3, "\n"; // 110 | 011 = 111
echo 6 ^ 3, "\n"; // 110 ^ 011 = 101
echo ~6, "\n"; // 取反
echo 1 << 4, "\n"; // 左移 = 乘 2^4
echo 256 >> 4, "\n"; // 右移 = 除 2^4Output
2
7
5
-7
16
16位运算最常见的用途是权限位:用 1 << n 表示第 n 个权限,& 判断有没有,| 授予,^ 撤销。
PHP
<?php
const READ = 1 << 0; // 1
const WRITE = 1 << 1; // 2
const EXECUTE = 1 << 2; // 4
$perm = READ | EXECUTE;
echo $perm, "\n"; // 5
var_dump((bool)($perm & READ)); // true
var_dump((bool)($perm & WRITE)); // false
$perm |= WRITE;
echo $perm, "\n"; // 7
$perm &= ~EXECUTE;
echo $perm, "\n"; // 3Output
5
bool(true)
bool(false)
7
3运算符优先级
不需要背全表,记住几条高危的即可:
.和+-同级且左结合 ——1 . 2 + 3是(1 . 2) + 3=12 + 3= 15,不是1 . 5!高于&&||,但!低于==——!$a == $b是!($a == $b)andorxor低于=—— 赋值后再逻辑运算??右结合 ——$a ?? $b ?? $c从右往左兜底
拿不准就加括号。括号不花钱,猜错优先级要调半天。