Вопрос по switch-statement, php – Ошибка оператора переключения php на int = 0

2

Я имею проблему в случае переключателя php.

Когда я установлю$number=0 это должно бежать самое первоеcase но вот этот код возвращает10-20K это во втором случае.

Я проверил операторы сравнения, проверил их, если еще они возвращают правильные значения, но здесь первый случай не работает$number=0

Почему это происходит ? php считает 0 ложным или что-то не так в коде?

Ссылка на кодовую вставку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;
}

?>

Ваш Ответ

7   ответов
0

Вы действительно не можете переключать регистр для диапазона числа. Для этого используйте if () {} else {}.

2

Когда вы выполняете метод переключения регистра, вы не можете сопоставить логическое значение, подобное этому. Вам нужно только сравнить полученное значение.

Я думаю, что вы должны переписать свой код для использования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 Заявление, вы уже знаете, что значениеnot меньше чем (или равно)1000 поэтому этоmust быть больше чем10000.

4
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 );
}
Более простой? Мне это не похоже. Меньше кода - да, но читаемость здесь страдает.
Большое спасибо ... Отличный ответ ... Jagdeep Singh
@JagdeepSingh: потому что иногда одна строка не является описательной, и через 3, 4, 5 месяца вы вообще не будете знать, что делает этот код.
@JagdeepSingh Добро пожаловать :)
@Lix Хорошо, это просто личный вкус.
3
$number = 0;
var_dump($number); // int(0)

Если вы измените заявление, чтобы бытьcase ($number > 0 && $number <= 10000):Странно работает. Но это работает с любым произвольным поиском ($number > 9091 && $number <= 10000) поступил.

Даже с полным замком ниже:

$number = 0;
$jonskeet = false;

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

Будет выводить0-10K хотя такое же состояние вif Заявление не сработает.

Проблема в том, чтоselect не должен использоваться с длинными условными выражениями.select может быть использован, чтобы сделать что-то, если значение переменнойis equal to что послеcase ключевое слово. Увидеть:

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

Но у вас есть длительные условия вcaseс вашего кода.

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

Запуск этого первого переводит$number <= 10000 вTRUE а также$number > 10000 && $number <= 20000 вFALSEвроде двух утверждений. И после этого ваш код выполняется следующим образом:

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

$number является0, но это может означатьFALSE тоже, поэтому вы получаете нежелательный результат.

В качестве решения вы должны перевести свой код, чтобы иметьif-elseif-else настроить:

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

Да для PHP0 являетсяFALSE (если вы не используете===). И да, ваш код неверен -switch не для сравнения диапазонов - это для сравнения значений (по крайней мере, в PHP, в Ruby или Perl 6, это другое дело), как здесь.

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

В вашем случае вы сравниваете число с условиями - те либо возвращаютtrue или жеfalse, Как0 являетсяfalseВторое условие ловит.switch не был сделан для такого кода, я хотел бы использоватьif else вместо этого или переписать свою логику - повторение не является хорошей идеей.

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

(кстати, я знаю, чтоswitch (true) работает, но не пользуюсь - это безобразный хак)

1

Здесь, если $ i равно 0, PHP выполнит все операторы echo!

поэтому его выполнить оператор следующего случая, и в этом случае есть выход из него

так что используйте if-else-if вместо переключателя

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, он выполнит 2-й случай, затем прервет; потому что в первом случае он будет проверять $ number (0 действует как false) == ($ number & lt; = 10000) (действует как true) // so false == true // результат false аналогично, условие становится истинным во втором, поэтому это было выполнение 2-го дела. Спасибо :) Jagdeep Singh
4

Выalmost с использованием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 usually looks terribly counter-intuitive the first time you see it. Please do not use it if you don't feel comfortable with it.
  2. Your conditionals could be simplified -- assuming they appear in order, each $number > X part is made redundant by the fact that the check in the previous conditional ($number <= X) has already failed. However, it can be argued that keeping the checks makes the code more robust in the face of modification.
именно то, что я искал ... спасибо :) Jagdeep Singh

Похожие вопросы