如何在PHP中使用switch case 'or'?

262

有没有办法在 PHP switch 语句中使用“OR”运算符或等效的方式?

例如,像这样:

switch ($value) {

    case 1 || 2:
        echo 'the value is either 1 or 2';
        break;
}
12个回答

565
switch ($value)
{
    case 1:
    case 2:
        echo "the value is either 1 or 2.";
    break;
}

这被称为“穿透”案例块。该术语存在于大多数实现switch语句的语言中。


150

如果你必须在 switch 中使用 || ,那么可以尝试:

$v = 1;
switch (true) {
    case ($v == 1 || $v == 2):
        echo 'the value is either 1 or 2';
        break;
}

如果这不是你首选的解决方案,那么原本你喜欢的解决方案是什么


switch($v) {
    case 1:
    case 2:
        echo "the value is either 1 or 2";
        break;
}
问题在于,当处理大的情况时,两种方法都不够有效... 想象一下1100,这将完美地运作。
$r1 = range(1, 100);
$r2 = range(100, 200);
$v = 76;
switch (true) {
    case in_array($v, $r1) :
        echo 'the value is in range 1 to 100';
        break;
    case in_array($v, $r2) :
        echo 'the value is in range 100 to 200';
        break;
}

2
“switch (true)”是一种反模式,它消除了switch块的唯一好处——单个评估。相反,需要评估每个case,并且所有的“break”调用都会使代码变得冗长。在专业项目中,我永远不会使用这种反模式。 - mickmackusa

59

我不会重新发布其他答案,因为它们都是正确的,但我会补充一点,如果你需要测试一个值是否“大于3”,“在4到6之间”等更“复杂”的条件语句,就不能使用switch。 如果你需要做这样的事情,请坚持使用if语句,或者如果有特别强烈的需要使用switch,那么可以反过来使用它:

switch (true) {
    case ($value > 3) :
        // value is greater than 3
    break;
    case ($value >= 4 && $value <= 6) :
        // value is between 4 and 6
    break;
}

但是就像我之前说过的,我个人会在那里使用一个if语句。


2
很高兴看到你在这种情况下推荐使用if()而不是switch()。在我看来,这种类型的switch只会增加复杂性。 - moo
1
是的,如果您选择这种样式,必须有一个相当令人信服的理由,但了解到它是可能的也是很好的。 - nickf
2
我很高兴学到这个。每次我在一种类似Basic的语言中构建项目时,我都会想念C风格的switch(),而当我在一种类似C的语言中工作时,我真的很想念Select Case,它实际上是一种简写方式,表示“这里有一个大块的if、else if、else-if……”。 - Stan Rogers
6
“你不能使用switch语句处理更复杂的语句”是指“不能”还是“不应该”?因为在你的示例中,你是可以使用的。“you can't use switch for more 'complicated' statements” 的意思是不能使用 switch 语句处理更加复杂的语句。在我的示例中,我只是演示了一个可以使用 switch 语句的简单情况,并不代表在所有情况下都可以使用 switch 语句。 - Sharky
@Sharky 他的意思是普通的 switch 用法不能做到这一点。switch (true) 这种用法并不是 switch 的普通用法。 - Chen Li Yong
1
switch (true)是一种反模式,它消除了switch块的唯一优点--单个评估。相反,需要对每个case进行评估,并且所有的break调用都会使代码变得冗长。在职业项目中,我绝不会使用这种反模式。 - mickmackusa

40

请使用本文中提供的以下示例进行尝试:http://phpswitch.com/

可能的开关案例:

(i). 一个简单的开关语句

开关语句是一种奇妙而神奇的结构。它是语言的一部分,允许您选择设置的不同选项,并根据设置的值运行不同的代码。

开关语句中每个可能的选项都由一个case表示。

示例:

switch($bar)
{
    case 4:
        echo "This is not the number you're looking for.\n";
        $foo = 92;
}

(ii). 分隔代码块

switch的主要注意点是,除非你使用break来停止它,否则每个case将会顺序执行到下一个case。如果上面的简单示例扩展到包含case 5:

示例:

case 4:
    echo "This is not the number you're looking for.\n";
    $foo = 92;
    break;

case 5:
    echo "A copy of Ringworld is on its way to you!\n";
    $foo = 34;
    break;

(iii). 多个 case 中使用 fallthrough

由于 switch 语句会一直执行代码,直到找到 break 语句,因此可以很容易地利用 fallthrough 的概念,在多个 case 中运行相同的代码:

示例:

case 2:

case 3:
case 4:
    echo "This is not the number you're looking for.\n";
    $foo = 92;
    break;

case 5:
    echo "A copy of Ringworld is on its way to you!\n";
    $foo = 34;
    break;

(iv). 高级开关:条件情况

PHP的switch不仅允许您切换特定变量的值:只要它为案例提供一个值,就可以使用任何表达式作为其中之一。 以下是使用switch编写的简单验证器示例:

示例:

switch(true)
{
    case (strlen($foo) > 30):
        $error = "The value provided is too long.";
    $valid = false;
    break;

    case (!preg_match('/^[A-Z0-9]+$/i', $foo)):
        $error = "The value must be alphanumeric.";
    $valid = false;
    break;

    default:
    $valid = true;
    break;
}

我认为这可能有助于解决您的问题。


你有关于示例(iv)的任何实际应用案例吗? - Pedro Moreira
“switch (true)”是一种反模式,它消除了switch块的唯一好处——单个评估。相反,需要评估每个case,并且所有的“break”调用都会使代码变得冗长。在专业项目中,我永远不会使用这种反模式。 - mickmackusa

15
尝试
switch($value) {
    case 1:
    case 2:
        echo "the value is either 1 or 2";
        break;
}

12

我建议你阅读 switch (手册)。

switch ($your_variable)
{
    case 1:
    case 2:
        echo "the value is either 1 or 2.";
    break;
}

说明

与想要执行单个语句的值一样,您可以将其放在没有 break 的情况下作为 until 或 unless,直到找到 break 为止继续执行代码,如果找到 break,它将退出 switch case。


我会再次缩进 break,这样开发人员的眼睛可以快速跟踪 case 表达式。 - mickmackusa

9

匹配表达式(PHP 8)

PHP 8 引入了新的match表达式,类似于switch语句,但具有更短的语法和以下区别:

  • 不需要break语句
  • 使用逗号组合条件
  • 返回一个值
  • 使用严格类型比较
  • 要求比较是穷尽的(如果没有找到匹配项,则会抛出一个UnhandledMatchError

示例:

match ($value) {
  0 => '0',
  1, 2 => "1 or 2",
  default => "3",
}

虽然这是正确的,但它实际上与问题无关。switch已经提供了一种以上的方式来完成OP想要的事情。 - yivi
3
话虽如此,这个页面代表了一个绝佳的机会,来推广 PHP 中一个极好、现代、替代性的特性。 - mickmackusa
+1 提醒我这个,真是太疯狂了,matchif-elseswitch 更简洁。 - undefined

2
请注意,您还可以使用闭包将 switch 的结果(使用早期返回)分配给变量:
$otherVar = (static function($value) {
    switch ($value) {
        case 0:
            return 4;
        case 1:
            return 6;
        case 2:
        case 3:
            return 5;
        default:
            return null;
    }
})($i);

当然,这种做法已经过时了,因为正是新的 PHP 8 match 函数 的目的,如 _dom93 答案中所示。

1
请使用以下代码:
switch($a) {
    case 1:
    case 2:
        .......
        .......
        .......
        break;
}

该块同时适用于1和2。


0
switch ($value) 
{
   case 1:
   case 2:
      echo 'the value is either 1 or 2';
   break;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接