【问题标题】:problem with conditional switch条件切换问题
【发布时间】:2010-12-21 11:28:16
【问题描述】:

以下示例摘自http://php.net/manual/de/control-structures.switch.php

<?php
$totaltime = 0;
switch ($totaltime) {

    case ($totaltime < 1):
        echo "That was fast!";
        break;

    case ($totaltime > 1):
        echo "Not fast!";
        break;

    case ($totaltime > 10):
        echo "That's slooooow";
        break;
}

?>

我预计结果是“很快”。但实际结果是“不快!”。如果有人能解释一下为什么会很棒?

但如果我添加另一个案例,case 0: echo "That was super fast!". 那么它会正确回显。即“那是超级快!”。请帮助我如何使用条件 switch 语句。

编辑:-

感谢大家的回复。我可以通过将 switch($totaltime) 修改为 switch(1) 来克服上述问题

【问题讨论】:

  • = Switch 只评估一次,你似乎误用了它

标签: php switch-statement


【解决方案1】:

case ($totaltime &lt; 1): 对 PHP 表示 1(该等式返回 true)

case ($totaltime &gt; 1): 对 PHP 表示 0(该等式返回 false)

由于 $totaltime 为 0,因此您将获得该输出

换句话说,PHP 将$totaltime 与比较结果进行比较。

编辑关于 OP 中的编辑:

你需要去掉switch()-statement。您只能使用它轻松地与不同的值进行比较,而不是使用其他表达式。

我的意思是有什么问题

<?php
$totaltime = 0;

if ($totaltime < 1) {
    echo "That was fast!";
} else if ($totaltime > 10) {
    echo "That's slooooow";
} else if ($totaltime > 1) {
    echo "Not fast!";
}

?>

编辑:请注意,我切换了最后两个 if 语句以使其真正起作用。

【讨论】:

  • - 完全没有错。但我有近 20 个值需要比较和显示错误。所以我认为 switch 会让它更具可读性而不是 IF。
  • @lucky:但你明白使用一组if() 语句更具可读性吗?这也意味着更少的代码导致出现错误的机会更少(不过,这更像是一般规则)。
【解决方案2】:

你不要在 case 这样的语句中使用条件,反正不直观。这就是正在发生的事情:

    case ($totaltime < 1):  // Evaluates to 1.  $totaltime is not 1, so no match.
    case ($totaltime > 1):  // Evaluates to 0.  $totaltime is 0, so match.

本质上,您正在尝试将 else if 构造用作 switch 构造,但功能不存在。条件不会以您期望的方式评估(它们在if 块中的方式),它们只是在寻找第一个case 块,它等于在switch 块中测试的值.

【讨论】:

    【解决方案3】:

    讨厌删除已经回答的帖子,但我很困惑没有人触及 switch(true) 方法。

    这两种方法在现实世界中都没有速度优势

    在某些情况下 switch 更快,其他情况下 if 更快,但只有几分之一微秒 (48.16 µs 与 49.11 µs 的切换速度比 if 快)。

    编辑

    现在我看到 OP 也做了同样的事情......

    <?php
    for ( $totaltime = 0; $totaltime < 11; $totaltime += 0.5 ) {
        switch ( true ) {
            case ( $totaltime < 1 ):
                echo $totaltime . " That was fast!\n";
                break;
            case ( $totaltime < 10 ):
                echo $totaltime . " Not fast!\n";
                break;
            default:
                echo $totaltime . " That's slooooow\n";
                break;
        }
    }
    

    结果:https://3v4l.org/d71lZ

    0 That was fast!
    0.5 That was fast!
    1 Not fast!
    1.5 Not fast!
    2 Not fast!
    2.5 Not fast!
    3 Not fast!
    3.5 Not fast!
    4 Not fast!
    4.5 Not fast!
    5 Not fast!
    5.5 Not fast!
    6 Not fast!
    6.5 Not fast!
    7 Not fast!
    7.5 Not fast!
    8 Not fast!
    8.5 Not fast!
    9 Not fast!
    9.5 Not fast!
    10 That's slooooow
    10.5 That's slooooow
    

    【讨论】:

      【解决方案4】:

      这似乎是一个布尔转换问题。

      第一个 case 语句将评估为 0 以外的任何值,因此不会命中。

      但第二个 case 语句将评估为 false,它应该是 0,等于您设置的 $totaltime。

      【讨论】:

        【解决方案5】:

        幸运,

        PHP 开关与一系列 IF 语句相同。案例评估为:

        if($totaltime == ($totaltime < 1)) {
          echo "That was fast!";
          break;
        }
        if($totaltime == ($totaltime > 1)) {
          echo "Not fast!";
          break;
        }
        ...
        

        显然 0 == false 表示第二个 IF 为真,因此结果。

        谢谢, 维卡斯。

        【讨论】:

          【解决方案6】:

          其他人提到了为什么会发生这种情况(在 case 语句中滥用条件),但他们没有提供替代方案。 Switch 旨在涵盖特定的参数,如 { 0, 1, 2, 3..100, 101 } 等。它分离出特定的参数或范围,而不是执行简单的 if/else(如您所用)。你可以重写你的论点来实现它:

          switch ($totaltime) {
          
              case (0):
                  echo "That was fast!";
                  break;
          
              case (1..PHP_INT_MAX):
                  echo "Not fast!";
                  break;
          
              default:
                  echo "That's slooooow";
                  break;
          }
          

          这里的 .. 允许覆盖一个范围,因此从 1 到整数最大值的任何内容都被这种情况覆盖。 0 被显式处理,所有其他 (re:

          【讨论】:

          • +1,感谢您的回复。这就是我要找的。当 $totaltime = 10;结果是“太慢了”;而不是“不快!”;
          • -1 PHP 不支持您在 switch/case 中使用的范围。您的 case (1..PHP_INT_MAX): 实际上将返回 1 和 PHP_INT_MAX (12147483647) 的串联值。我猜你最近做了太多 Pascal 并且正在混合 PHP 和 Pascal 语法:p.
          • @wimvds:感谢您的评论和信息。我想我最近在其他语言上花费了太多时间。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多