Расхождение в результатах оператора switch - PullRequest
0 голосов
/ 17 февраля 2010
function skyCoverage( $metarClouds ) {

    foreach( $metarClouds[0] as $cloudReport ) {
        $coverageCode = substr( $cloudReport, 0, 3 );

        // I check $coverageCode here, and it is indeed "CLR"

            switch( $coverageCode ) {
                case "CLR":
                    $cloudCoverage = 0;
                    break;
                case "FEW":
                    $cloudCoverage = 1/8;
                    break;
                case "SCT":
                    $cloudCoverage = 3/8;
                    break;
                case "BKN":
                    $cloudCoverage = 5/8;
                    break;
                case "OVC":
                    $cloudCoverage = 8/8;
                    break;
            }
    $skyCoverage = $skyCoverage + $cloudCoverage;
    }

// I check $skyCoverage here, and it is indeed 0

    switch ( $skyCoverage ) {
        case ( $skyCoverage >= 1.00 ):
                $skyCondition = "Overcast";
                // I do an echo $skyCoverage; here, and it actually spits out 0 still, even though it obviously shouldn't do anything at all
                break;
        case ( $skyCoverage >= 0.75 ):
                $skyCondition = "Cloudy";
                break;
        case ( $skyCoverage >= 0.625 ):
                $skyCondition = "Mostly Cloudy";
                break;
        case ( $skyCoverage >= 0.5 ):
                $skyCondition = "Scattered Clouds";
                break;
        case ( $skyCoverage >= 0.375 ):
                $skyCondition = "Partly Cloudy";
                break;
        case ( $skyCoverage >= 0.125 ):
                $skyCondition = "Mostly Clear";
                break;
        case ( $skyCoverage < 0.125 ):
                $skyCondition = "Clear";
                break;
    }

// $skyCoverage is still zero here

return $skyCondition;
// Somehow $skyCondition is "Overcast" with $skyCoverage = 0

}

Как правило, наблюдается более одного облачного слоя и, следовательно, каждый $cloudCoverage в слое добавляется к другому при цикле по $metarClouds[0]. Однако, если облачного слоя нет (clear или "CLR"), он должен быть зарегистрирован как 0. И это происходит. Однако код как-то возвращает «Overcast».

Я проверил оба оператора switch, чтобы убедиться, что CLR передается, когда я ожидаю, и что $cloudCoverage равняется нулю, когда я ожидаю. Это каждый раз. И, $skyCoverage все еще регистрируется как ноль непосредственно перед возвратом.

Я попытался установить $cloudCoverage в 1-1, 0/1, 0.0 или каким-либо другим способом, чтобы гарантировать, что PHP как-то не воспринимает его как нуль и ... каким-то образом ... обрабатывает его неправильно. Если я переписываю так, чтобы $cloudCoverage = 0.01 и пропустил CLR через первый коммутатор, все прошло через второй коммутатор правильно: Очистить. Я также попытался установить в последнем случае значение case 0: и т. Д., Но все равно получил тот же ошибочный результат.

Ответы [ 3 ]

2 голосов
/ 17 февраля 2010

Давайте подробнее рассмотрим, как

switch ( $skyCoverage ) {
  case ( $skyCoverage >= 1.00 ):

оценивается. Сначала давайте заменим $ skyCover на 0

switch ( 0 ) {
  case ( 0 >= 1.00 ):

Теперь оцените состояние дела

switch ( 0 ) {
  case ( false ):

А так как (bool) 0 === false, это совпадение
(см. http://docs.php.net/language.types.boolean#language.types.boolean.casting).
Как сказал pygorex1, это не так switch/case работает. Вы хотите

if (...) {
}
else if (...) {
}
else {
}

вместо.

(правка: использование "идентичного оператора" === в "(bool) 0 === false" не очень хорошее объяснение. Switch / case выполняет произвольное сравнение , т.е. жонглирование типа , как в 0 == false, что оценивается как ИСТИНА)

1 голос
/ 17 февраля 2010

Это не так, как switch операторы работают:

http://us.php.net/manual/en/control-structures.switch.php

Редактировать: взять этот фрагмент кода:

switch ( $skyCoverage ) {
    case ( $skyCoverage >= 1.00 ):
            $skyCondition = "Overcast";

Когда $skyCoverage равно 0, оператор $skyCoverage >= 1.00 будет иметь значение false. Таким образом, оператор case ( $skyCoverage >= 1.00 ) оценивается следующим образом: case ( false ), а с 0 == false конечный результат будет Overcast

0 голосов
/ 17 февраля 2010

Я думаю, что проблема в том, что:

( $skyCoverage >= 1.00 )

оценивается как false или 0, и, когда вы сравниваете его с $ skyCoverage (0), автоматически выбирается первый.

...