Menu

PHP switch 语句:case、break 与贯穿

switch ($value) 把一个值和一组 case 标签逐一比较,从第一个匹配的地方开始运行代码,直到遇到 break。内容包括多个 case 共用代码、贯穿、default、switch(true),以及为什么 switch 使用宽松的 == 比较。

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

switch ($value) 把一个值和一组 case 标签逐一比较,运行第一个匹配的标签下面的代码。每个 case 以 break 结束;default 处理所有都没匹配上的情况。

把 $day 改成 'fri'、'sun' 或 'wed',再运行一次。default 放在最后时不需要 break。

多个 case 共用一段代码

要让几个值运行同一段代码,就把 case 标签叠在一起,中间什么都不写。匹配的标签会接着运行下面的代码。

和 match 不同,switch 没有 case 'jpg', 'jpeg': 这样的逗号写法。叠加标签是唯一的办法。

贯穿:没有 break 会怎样

让 switch 停下来的是 break。没有它,PHP 运行完匹配的 case 后,会忽略下面各个 case 的标签,继续往下运行,直到遇到 break 或结尾。

这里的贯穿是有意的:每个套餐都拥有自己的功能,再加上所有更便宜套餐的功能。如果是故意这么写,加一行 // no break 这样的注释,免得后来的人把它“修好”。如果不是故意的,漏写 break 是 switch 最常见的 bug 之一。

switch 使用宽松比较(==)

每个 case 都用 == 检查,而不是 ===。数字字符串能匹配数字,null 能匹配 false 和 "",true 能匹配任何被当作真的值。点击单元格,对比这两个运算符。

switch 用 == 比较,match 用 === 比较
Point at or tap a cell to read it as PHP.
$a == $b01"0""1"""nullfalsetrue"a""10""1e1"
0
1
"0"
"1"
""
null
false
true
"a"
"10"
"1e1"
Every cell computed by PHP 8.3.19.

实际影响是:表单传来的字符串 "1" 不用任何转换就能进入 case 1:,这往往正是你想要的。但 switch (true) 遇上非空字符串,或者 null 遇上 case false:,都可能选中你意想不到的 case。

注意 null 那一行:它永远到不了 case false:,因为 null == 0 已经为真,而 case 0: 排在前面。在宽松比较下,case 的顺序会改变结果。从 PHP 8 开始,0 == "a" 为假(PHP 7 中为真),所以非数字字符串不再匹配 case 0:。如果你需要 ===,用 match 表达式,本页最后会讲到。

用 switch(true) 判断范围和条件

case 标签可以是任意表达式。用 switch (true) 时,每个 case 都是一个条件,第一个等于 true 的胜出。

确保每个 case 都是真正的布尔值。由于是宽松比较,只要 $name 是非空字符串,case $name: 就会匹配。

循环中的 switch:break 和 continue

在循环里,switch 中的 break 只会跳出 switch,而不会跳出循环。要停止循环,用 break 2。switch 里的 continue 和 break 效果一样,PHP 会在编译时给出警告:"continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?。要跳到循环的下一轮,写 continue 2。

switch 与 match

PHP 8 新增了 match,它能用更少的代码覆盖 switch 的大多数用法。它用 === 比较,返回一个值,从不贯穿,允许用逗号分隔多个条件,而且在没有任何匹配时抛出 UnhandledMatchError,所以漏掉的 case 不会悄悄溜过去。

当一个 case 需要多条语句,或者贯穿正是你想要的效果(比如前面套餐的例子)时,继续用 switch。要把一个值映射成一个结果,match 更简短也更安全。

常见问题

PHP switch 中怎么让多个 case 共用一段代码?

把 case 标签叠在一起,中间不写代码:case 'sat': case 'sun': echo 'weekend'; break;。每个标签都会贯穿到共用的代码。PHP 的 switch 没有 case 'sat', 'sun': 这种写法,逗号形式属于 match。

PHP 的 switch 使用严格比较吗?

不是。switch 用宽松的 == 比较,所以 case '1': 能匹配整数 1,case 0: 能匹配 '0'。需要严格的 === 比较时,用 match 表达式,或者用 switch (true) 并在每个 case 里写 ===。

PHP switch 中忘了写 break 会怎样?

执行会贯穿下去:匹配的 case 运行完后,PHP 会继续运行它下面每个 case 的代码,直到遇到 break、return 或 switch 的结尾。有时这是有意为之,但通常是个 bug。

PHP switch 能判断“大于”这样的范围吗?

能,用 switch (true):每个 case 写一个条件,比如 case $score >= 90:,第一个为真的条件会被执行。match (true) 表达式用严格比较做同样的事,并返回一个值。

Coddy 编程语言插图

和 Coddy 一起学编程

开始