主题
赋值运算符
赋值就是「把右边的值放进左边的变量」。最基本的就是 =,在 变量定义 里已经用过。这一篇把它和各种「算完再赋回去」的写法放在一起。
php
<?php
$score = 60;
$score += 15;
$score *= 2;
echo $score, "\n"; // 150一览
| 运算符 | 含义 | 等价写法 |
|---|---|---|
= | 赋值 | — |
+= | 加后赋值 | $a = $a + $b |
-= | 减后赋值 | $a = $a - $b |
*= | 乘后赋值 | $a = $a * $b |
/= | 除后赋值 | $a = $a / $b |
%= | 取余后赋值 | $a = $a % $b |
**= | 幂运算后赋值 | $a = $a ** $b |
.= | 拼接后赋值 | $a = $a . $b |
??= | 为空时才赋值 | $a = $a ?? $b |
左边必须是能放值的东西(变量、数组元素等),不能写 10 = $a。
普通赋值 =
php
<?php
$lang = "PHP";
$year = 1995;
$year = $year + 1; // 1996,读旧值、算完再写回去= 是右结合,可以连续赋值:
php
<?php
$a = $b = $c = 0;先把 0 赋给 $c,再赋给 $b,再赋给 $a。三个变量拿到的是拷贝后的值,互不影响。引用赋值 $b = &$a 见 变量定义。
赋值表达式本身的值,就是赋进去的那个值:
php
<?php
$n = ($m = 8);
echo $n, "\n"; // 8正因为如此,if ($user = findUser()) 这种「赋值当条件」能跑,但很容易看成 ==。初学阶段条件判断请用 比较运算符,不要在 if 里赋值。
复合赋值
「用自己的旧值算一下,再存回去」时,用复合赋值更短:
php
<?php
$count = 10;
$count += 2; // 12
$count -= 5; // 7
$count *= 3; // 21
$count /= 7; // 3
$count %= 2; // 1
$count **= 4; // 1
echo $count, "\n";算术规则和 算术运算符 完全一样,包括除以零、字符串转数字这些细节。
只改一,也可以继续用 ++ / --:
php
<?php
$page = 1;
$page += 1; // 2
$page++; // 3,效果类似,但 ++ 只能加减 1字符串拼接 .=
. 是拼接,.= 是「在后面追加」:
php
<?php
$msg = "Hello";
$msg .= ", ";
$msg .= "PHP";
$msg .= "\n";
echo $msg; // Hello, PHP追加一段 HTML 或日志时很常见。注意是点号,不是加号:$msg += "PHP" 会按数字去加,结果不对。
空合并赋值 ??=
?? 的意思是「左边是 null 或未定义时,用右边」。和 ? :、?: 的对照见 三元运算符。??= 则是「只有为空时才写入」:
php
<?php
$title = null;
$title ??= "未命名";
echo $title, "\n"; // 未命名
$title ??= "首页";
echo $title, "\n"; // 仍是 未命名,因为已经有值了适合给缺省值,又不会把已有的内容覆盖掉:
php
<?php
$config = [];
$config["lang"] ??= "zh-CN";
$config["lang"] ??= "en";
echo $config["lang"], "\n"; // zh-CN和 empty() 不同:0、""、false 对 ?? / ??= 来说都算「有值」,不会被替换。只有 null 和未定义才会用右边。
赋值不是比较
这是最常见的笔误:
php
<?php
$score = 60;
if ($score = 100) { // 错:这里把 100 赋给了 $score,条件恒为真
echo "满分\n";
}
echo $score, "\n"; // 100,原值已经被改掉比较是否相等要用 == 或 ===,见 比较运算符。
和逻辑运算写在一起时
and / or 的优先级低于赋值,&& / || 高于赋值。于是:
php
<?php
$ok = true and false;
var_dump($ok); // true,实际是 ($ok = true) and false需要「算完逻辑再赋给变量」时,用 && / ||,或加上括号。详情见 逻辑运算符。
书写建议
- 条件里不要赋值,避免
=/==看走眼 - 能用
+=、.=就不要把变量名写两遍 - 缺省值用
??=,不要先isset再手动赋值(除非还要同时排除0、"") - 复合赋值左边的变量只求值一次,数组里写
$arr[$i++] += 1这类代码请避开
练习
$price初始为100,连续使用-=、*=表示先减20再打8折,输出最终价格。- 用
.=把姓、名拼成一句姓名:张三。 $theme为null时用??=设成light;再执行一次??= 'dark',确认不会被覆盖。- 故意写一次
if ($n = 1),用var_dump($n)观察变量被改成了什么,然后改成正确的比较。