【问题标题】:php switch statement error on int = 0int = 0上的php switch语句错误
【发布时间】:2012-09-30 09:29:17
【问题描述】:

我在 php switch case 中遇到问题。

当我设置 $number=0 时,它应该运行第一个 case 但这里的代码返回 10-20K 是第二种情况.

我检查了比较运算符,在 if else 情况下测试它们返回正确的值,但这里第一种情况不在 $number=0

上运行

为什么会这样? php 认为 0 为 false 或代码有问题?

链接到键盘粘贴http://codepad.org/2glDh39K

这里也是代码

<?php

$number = 0;

    switch ($number) {
     case ($number <= 10000):
            echo "0-10K";
           break;
        case ($number > 10000 && $number <= 20000):
            echo "10-20K";
            break;
        case ($number > 20000 && $number <= 30000):
            echo "20-30K";
            break;
        case ($number > 30000 && $number <= 40000):
            echo "30-40K";
            break;
        case ($number > 40000 && $number <= 50000):
            echo "40-50K";
            break;
        case ($number > 50000 && $number <= 60000):
            echo "50-60K";
            break;
        case ($number > 60000 && $number <= 70000):
            echo "60-70K";
            break;
        case ($number > 70000 && $number <= 80000):
            echo "70-80K";
            break;
        case ($number > 80000 && $number <= 90000):
            echo "80-90K";
            break;
        case ($number > 90000):
            echo "90K+";
            break;

        default: //default
            echo "N/A";
            break;
}

?>

【问题讨论】:

    标签: php switch-statement


    【解决方案1】:

    几乎在反向使用 switch,但不完全是。您需要通过编写switch(true) 完全反转:

    switch (true) { // IMPORTANT CHANGE HERE!
        case ($number <= 10000):
            echo "0-10K";
           break;
        case ($number > 10000 && $number <= 20000):
            echo "10-20K";
            break;
        // etc
    }
    

    或以其他方式将整个内容更改为if/else:

    if ($number <= 10000) {
        echo "0-10K";
    else if ($number > 10000 && $number <= 20000) {
        echo "10-20K";
    }
    // etc
    

    两个重要说明:

    1. Reverse switch 在您第一次看到它时通常看起来非常违反直觉。如果您觉得不舒服,请不要使用它。
    2. 您的条件可以被简化——假设它们按顺序出现,每个$number &gt; X 部分都是多余的,因为前一个条件 ($number &lt;= X) 中的检查已经失败。但是,可以说保留检查使代码在面对修改时更加健壮。

    【讨论】:

      【解决方案2】:
      switch ($number) {
       case ($number <= 10000):   // check $number == ($number <= 10000)
             echo "0-10K";
             break;
       // you hit the below because `0 == false` is true in php
       case ($number > 10000 && $number <= 20000): // check $number == ($number > 10000 && $number <= 20000)
              echo "10-20K";
              break;
       // ...
      

      但你可以用更少的代码做到这一点:

      function showRange($number) {
          if ($number > 90000) {
             echo "90K+";
             return;
          }
          echo sprintf("%s-%sK", (int) ($number / 10000) * 10, ((int) ($number / 10000) +1) * 10 );
      }
      

      【讨论】:

      • 更简单?在我看来不像。更少的代码 - 是的,但这里的可读性受到影响。
      • @Lix 好吧,这只是个人品味。
      • @JagdeepSingh:因为有时,一行不是描述性的,在 3、4、5 个月后,你根本不知道这段代码做了什么。
      • @MadaraUchiha - 没错,但我认为这就是 cmets 在编程语言中的用途。
      【解决方案3】:

      当你执行一个 switch case 方法时,你不能匹配一个像这样的布尔值。您只需比较结果值。

      我认为您应该重写代码以使用 if...then...elseif 语句。

      if ($number <= 10000){
        echo "0-10K";
      }elseif($number <= 20000){
        echo "10-20K";
      }elseif($number <= 30000){
        echo "20-30K";
      }elseif($number <= 40000){
        ...
      }
      

      通过使用这种方法,您不需要每次都进行两次检查,因为前面的if 语句也会检查这些条件。 IE:如果您到达第二个if 语句,您已经知道该值小于(或等于)1000,因此它必须大于10000.

      【讨论】:

        【解决方案4】:
        $number = 0;
        var_dump($number); // int(0)
        

        如果将语句修改为case ($number &gt; 0 &amp;&amp; $number &lt;= 10000):,它会奇怪地起作用。但它适用于输入的任意查找 ($number &gt; 9091 &amp;&amp; $number &lt;= 10000)。

        即使下面是完整的废话:

        $number = 0;
        $jonskeet = false;
        
        switch ($number)
        {
            case ($jonskeet === true && $number <= 10000):
                echo "0-10K";
                // ...
        

        即使if 语句中的相同条件不起作用,它也会输出0-10K

        问题是select 不能与长条件一起使用。如果变量的值等于 case 关键字后面的值,select 可以用来做某事。见:

        select ($user_rank)
        {
            case 0:
                return "guest";
                break;
            case 1:
                return "user";
                break;
            // ...
            default:
                return "unknown";
                break;
        }
        

        但是您的代码的cases 中有很长的条件。

        case ($number <= 10000):
            echo "0-10K";
            break;
        case ($number > 10000 && $number <= 20000):
            echo "10-20K";
            break;
        

        首先运行它会将$number &lt;= 10000 转换为TRUE 并将$number &gt; 10000 &amp;&amp; $number &lt;= 20000 转换为FALSE,就像两个语句一样。在此之后,您的代码将按以下方式执行:

        case TRUE:
            echo "0-10K";
            break;
        case FALSE:
            echo "10-20K";
            break;
        

        $number0,但它也可以评估为 FALSE,这就是你得到不想要的输出的原因。

        作为一种解决方案,您应该将您的代码翻译成if-elseif-else 设置:

         if ( $number < 10000 ) {
             echo "0-10K";
         } else if ( $number > 10000 && $number <= 20000 ) {
             echo "10-20K";
         // ...
         } else {
             echo "N/A";
         }
        

        【讨论】:

          【解决方案5】:

          是的,对于 PHP,0FALSE(除非您使用 ===)。是的,您的代码不正确 - switch 不是用于比较范围 - 它是用于比较值(至少在 PHP、Ruby 或 Perl 6 中是另一回事),就像那里一样。

          switch ($letter) {
          case 'a':
              echo "A?";
              break;
          default:
              echo "Unknown letter";
              break;
          }
          

          在您的情况下,您将数字与条件进行比较 - 那些返回 truefalse。因为0false,所以第二个条件成立。 switch 不是为这样的代码而设计的,我会改用 if else 或重写你的逻辑 - 重复不是个好主意。

          $range_number = floor($number / 1000);
          echo $range_number, $range_number ? "K" : "", "-", $range_number + 1, "K";
          

          (顺便说一句,我知道switch (true) 有效,但不要使用它 - 这是丑陋的黑客)

          【讨论】:

            【解决方案6】:

            这里,如果 $i 等于 0,PHP 将执行所有的 echo 语句!

            所以它执行下一个案例的语句,在这种情况下,它会中断

            所以使用 if-else-if 代替 switch case

            if ($number <= 10000){
              echo "0-10K";
            }elseif(  $number <= 20000){
              echo "10-20K";
            }elseif(  $number <= 30000){
              echo "20-30K";
            }elseif(  $number <= 40000){
              echo "90K+";
            }
            
             ...
            
            elseif(  $number <= 90000)
                 echo "80-90K";
            
            }elseif($number > 90000){
            echo "90K+";
            }
            

            【讨论】:

            • 不需要那些额外的测试。如果我们已经到了第二个 if 语句,我们已经知道值大于 10000...
            • @Lix 我的意思是如果在 switch 中如果有 0 则所有情况都会被执行
            • @hakra - 首先感谢您的回答:) 在 switch 如果有 0 它将执行第二种情况然后中断;因为在第一种情况下,它会检查 $number(0 act as false) == ($number
            【解决方案7】:

            你不能真正为一个数字范围做 switch case。使用 if(){} else{} 来达到这个目的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-06-12
              相关资源
              最近更新 更多