官方文档定义:
switch 语句类似于具有同一个表达式的一系列 if 语句。很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码。这正是 switch 语句的用途。
现在来看一些示例:
$a = 1;
switch ($a) {
case 1:
echo "aaaa" . PHP_EOL;
break;
case 2:
echo "bbb" . PHP_EOL;
break;
case 3:
echo "ccc" . PHP_EOL;
break;
}
上面的这个情况我们应该都很清楚会输出 “aaaa” 对吧.
$a = 1;
switch ($a) {
case 1:
echo "aaaa" . PHP_EOL;
case 2:
echo "bbb" . PHP_EOL;
case 3:
echo "ccc" . PHP_EOL;
}
那这个例子呢? 程序执行后会输出什么. 经过实际执行会发现,三个输出语句都会被执行.
这是为什么呢?
仔细研究官方文档,官方对于这个情况是有提及的,
switch 语句一行接一行地执行(实际上是语句接语句)。开始时没有代码被执行。仅当一个 case 语句中的值和 switch 表达式的值匹配时 PHP 才开始执行语句,直到 switch 的程序段结束或者遇到第一个 break 语句为止。如果不在 case 的语句段最后写上 break 的话,PHP 将继续执行下一个 case 中的语句段。
也就是我们上面的那个例子了.
再来一个示例:
$a = 0;
switch ($a) {
case $a == 0:
echo "aaaa" . PHP_EOL;
break;
case $a > 0:
echo "bbb" . PHP_EOL;
break;
case $a < 0:
echo "ccc" . PHP_EOL;
break;
}
那这个例子呢? 程序执行后会输出什么.
如果没有实际去尝试,第一印象来选大概都会选择执行第一个输出语句对吧.但是,实际执行过后你会发现实际输出的是第二个语句的"bbb".
我们回头再看看官方关于switch的定义:
很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码
根据$a
等于遍历下来的哪个case的 值 来执行不同的代码. 是的,问题就是出在这里,如果case后面跟的是一个表达式, 实际上$a会与这个表达式的值进行比较,而不是判断这个case后表达式的真假.
所以上面的例子中,$a
会依次与 ($a == 0)
的值 也就是true比较. 0 == true
吗? 不等于,所以就跳过了.
还记得之前聊过的php8新增的match表达式吗?
顺便再回顾下php8 新增的match表达式与switch的区别
- match表达式中,与每个case的比较是一个
===
的强等的模式,而switch是弱等==
. - match表达式支持单个case中有多个可以比较的值选项,但是switch不支持这种写法.
- match表达式不需要插入break跳出,只要匹配到一个条件过后,就不会往下执行了.
- match表达式会将匹配到的case的右边的表达式的结果返回,如果没有返回值,默认的match返回值是null.