Несколько условий PHP для оператора if, который меняет цвет шрифта

У меня есть некоторые проблемы с этим кодом PHP:

 // HIGHLIGHT NUMBERS *************************************************
 // BUY
$valueEnlightOverBuy = $_POST["enlightOverBuy"];
$valueEnlightUnderBuy = $_POST["enlightUnderBuy"];

// GREEN PRICE BUY
$fontColorBuy = "#FFF"; 

    if ((($valueEnlightOverBuy != '') or ($valueEnlightUnderBuy != '')) and (($valueEnlightOverBuy and $valueEnlightUnderSell) != "0")) {
    if (($finalPriceBuyer >= $valueEnlightOverBuy) or ($finalPriceBuyer <= $valueEnlightUnderBuy)) {
    $fontColorBuy = "#00FF00";
    } else if (($finalPriceBuyer >= $valueEnlightOverBuy and $finalPriceBuyer <= $valueEnlightUnderBuy)) {
    $fontColorBuy = "#FF00FF";
    } else {
    $fontColorBuy = "#D00000";
    }};

 // SELL LOCAL
 $valueEnlightOverSloc = $_POST["enlightOverSloc"];
 $valueEnlightUnderSloc = $_POST["enlightUnderSloc"];

 // GREEN PRICE SELL LOCAL
 $fontColorSellLoc = "#FFF";    

    if ((($valueEnlightOverSloc != '') or ($valueEnlightUnderSloc != '')) & (($valueEnlightOverSloc & $valueEnlightUnderSloc) != "0")) {
    if (($finalPriceSellerLocal >= $valueEnlightOverSloc) or ($finalPriceSellerLocal <= $valueEnlightUnderSloc)) {
    $fontColorSellLoc = "#00FF00";
    } else if (($finalPriceSellerLocal >= $valueEnlightOverSloc) and ($finalPriceSellerLocal <= $valueEnlightUnderSloc)) {
    $fontColorSellLoc = "#FF00FF";
    } else {
    $fontColorSellLoc = "#D00000";
    }};

 // SELL INTERNATIONAL
 $valueEnlightOverSellInt = $_POST["enlightOverSellInt"];
 $valueEnlightUnderSellInt = $_POST["enlightUnderSellInt"];

 // GREEN PRICE SELL INTERNATIONAL
 $fontColorSellInt = "#FFF";    

    if ((($valueEnlightOverSellInt != '') or ($valueEnlightUnderSellInt  != '')) & (($valueEnlightOverSellInt & $valueEnlightUnderSellInt) != "0"))      {
    if (($finalPriceSellerInt >= $valueEnlightOverSellInt) or  ($finalPriceSellerInt <= $valueEnlightUnderSellInt)) {
    $fontColorSellInt = "#00FF00";
    } else if (($finalPriceSellerInt >= $valueEnlightOverSellInt) and  ($finalPriceSellerInt <= $valueEnlightUnderSellInt)) {
    $fontColorSellInt = "#FF00FF";
    } else {
    $fontColorSellInt = "#D00000";  
    }};

Как вы видите, у меня есть форма публикации (не показанная в коде), которая передает в этот файл значения для: VAR underBuy

Сначала код проверяет, являются ли VAR, полученные из формы, ПУСТОЙ или = к 0; если это не так, код собирает все эти данные и проверяет $FINALPRICEBUYER (извлеченный из файла с json) для первых двух VAR, а затем проверяет $FINALPRICESELLERLOCAL для третьего и четвертого VAR и, таким образом, проверяет на $ FINALPRICESELLERINT для 5-й и 6-й VAR.

Если $FINALPRICEBUYER находится между> = чем 1-ая VAR или <= чем 2-ая VAR, сделать шрифт ЗЕЛЕНЫМ, иначе, если $FINALPRICEBUYER между 3-ьим VAR и 4-ым VAR становится VIOLET, иначе - КРАСНЫМ.

То же самое для $FINALPRICESELLERLOCAL и $FINALPRICESELLERINT.

Я выполнил первые два условия, потому что пользователь может вставить один лимит цены или два.

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

Вот вопрос:

Этот код не работает. Много раз он возвращает зеленый шрифт, несмотря на фиолетовый, поэтому в логической структуре математических символов (или, конечно, PHP-кода) должно быть что-то, чего я не могу получить...

ОБНОВЛЕНИЕ 29.06.2015

Вот код, который я использую и адаптирую, начиная с ваших примеров.

// ENLIGHT NUMBERS ***************************************************

// get all input variables at once
$over_buy  = $_POST['enlightOverBuy'];
$under_buy = $_POST['enlightUnderBuy'];
$over_loc  = $_POST['enlightOverSloc'];
$under_loc = $_POST['enlightUnderSloc'];
$over_int  = $_POST['enlightOverSellInt'];
$under_int = $_POST['enlightUnderSellInt'];

$final_buy = $finalPriceBuyer;
$final_loc = $finalPriceSellerLocal;
$final_int = $finalPriceSellerInt;

// now set the colors
$buy = getFontColor( $over_buy, $under_buy, $final_buy );
$loc = getFontColor( $over_loc, $under_loc, $final_loc );
$int = getFontColor( $over_int, $under_int, $final_int );

Так что здесь нет ничего другого. Теперь функция:

 // function to return color based on input
 function getFontColor( $over, $under, $final ) {

 // colors
 $white  = '#fff';
 $green  = '#0f0';
 $violet = '#f0f';
 $red    = '#d00000';

Первый шаг: если функция получит номер 0, шрифт будет белым, поэтому:

 if ($final != '0') {

Второй шаг: если оба "значения" отправляются формой

     if (!empty($over) and !empty($under)) {

Третий шаг: если ФИНАЛ является числом между более или менее

           if ($final >= $over && $final <= $under) {

ЗЕЛЕНЫЙ

                  return $green;

если не

           } else {

КРАСНЫЙ

           return $red; 
           }

Четвертый шаг: иначе, если одно из значений или другое пустое

 } else if (!empty($over) or !empty($under)) {

Пятый шаг: если FINAL - это число, превышающее значение "over" или ниже значения "under"

        if ($final >= $over or $final <= $under) {

ЗЕЛЕНЫЙ

                return $green;

еще КРАСНЫЙ

        } else {
                return $red;
                }

Шестой шаг: в любом другом случае, БЕЛОЕ

 } else {
        return $white;
 }
 }};

Поэтому я бы выбрал ЗЕЛЕНЫЙ, если $ final находится между двумя значениями, полученными из формы, но если у вас есть только одно входное значение (таким образом, ниже или выше), если $ final выше, чем выше или ниже, чем ниже, перейдите в ЗЕЛЕНЫЙ. В любом другом казино идите КРАСНЫМ, если $ final не равен "0".

Вот полный код без пробелов:

// ENLIGHT NUMBERS ***************************************************

// get all input variables at once
$over_buy  = $_POST['enlightOverBuy'];
$under_buy = $_POST['enlightUnderBuy'];
$over_loc  = $_POST['enlightOverSloc'];
$under_loc = $_POST['enlightUnderSloc'];
$over_int  = $_POST['enlightOverSellInt'];
$under_int = $_POST['enlightUnderSellInt'];

$final_buy = $finalPriceBuyer;
$final_loc = $finalPriceSellerLocal;
$final_int = $finalPriceSellerInt;

// now set the colors
$buy = getFontColor( $over_buy, $under_buy, $final_buy );
$loc = getFontColor( $over_loc, $under_loc, $final_loc );
$int = getFontColor( $over_int, $under_int, $final_int );

 // function to return color based on input
 function getFontColor( $over, $under, $final ) {

 // colors
 $white  = '#fff';
 $green  = '#0f0';
 $violet = '#f0f';
 $red    = '#d00000';

 if ($final != '0') {
     if (!empty($over) and !empty($under)) {
           if ($final >= $over && $final <= $under) {
                  return $green;
           } else {
           return $red; 
           }
 } else if (!empty($over) or !empty($under)) {
        if ($final >= $over or $final <= $under) {
                return $green;
        } else {
                return $red;
                }
 } else {
        return $white;
 }
 }};

Мне кажется это правильным, но я получаю странный результат, эхо, которое вы увидите, было создано мной для проверки поведения функции.

1-й пример возврата

2-й пример возврата

3-й пример возврата

4-й пример возврата

Пожалуйста, не учитывайте мои комментарии на итальянском, но результат не имеет смысла, учитывая:

  • 1-й пример: ЗЕЛЕНЫЙ (0.127839 НЕ ниже 0.125, поэтому должен быть КРАСНЫМ) КРАСНЫЙ (правильно) - ЗЕЛЕНЫЙ (правильно)
  • 2-й пример: ЗЕЛЕНЫЙ (0.154761 НЕ ниже 0.125, поэтому должен быть КРАСНЫМ) - КРАСНЫЙ (правильный) - ЗЕЛЕНЫЙ (правильный)
  • 3-й пример: ЗЕЛЕНЫЙ (0,14442 НЕ ниже 0,125, поэтому должен быть КРАСНЫМ) - КРАСНЫЙ (правильный) - ЗЕЛЕНЫЙ (правильный)
  • 4-й пример: ЗЕЛЕНЫЙ (0.129195 НЕ ниже 0.125, поэтому должен быть КРАСНЫМ) - КРАСНЫЙ (правильный) - КРАСНЫЙ (правильный).

Как это возможно, что при использовании одной и той же функции вы всегда получаете ошибку при первом использовании и правильный ответ при следующих двух использованиях?

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ

Вот код:

 $over_buy  = number_format($_POST['enlightOverBuy'], 6);
 $under_buy = number_format($_POST['enlightUnderBuy'], 6);
 $over_loc  = number_format($_POST['enlightOverSloc'], 6);
 $under_loc = number_format($_POST['enlightUnderSloc'], 6);
 $over_int  = number_format($_POST['enlightOverSellInt'], 6);
 $under_int = number_format($_POST['enlightUnderSellInt'], 6);


 $final_buy = $finalPriceBuyer;
 $final_loc = $finalPriceSellerLocal;
 $final_int = $finalPriceSellerInt;

 // now set the colors
 $buy = getFontColor( $over_buy, $under_buy, $final_buy );
 $loc = getFontColor( $over_loc, $under_loc, $final_loc );
 $int = getFontColor( $over_int, $under_int, $final_int );


 // function to return color based on input
 function getFontColor( $over, $under, $final ) {

 // colors
 $white  = '#fff';
 $green  = '#0f0';
 $red    = '#FF3300';

 if ($final != '0') {
    if (!empty($over) and !empty($under)) {
        if ($final >= $over && $final <= $under) {
                return $green;
        } else {
                return $red; 
                }
 } elseif (!empty($over)) {
                return ($final >= $over) ? $green : $red;
 } elseif (!empty($under)) {
                return ($final <= $under) ? $green : $red;
 } else {
    return $white;
    }
 }};

3 ответа

Решение

Сначала вы должны проверить наиболее строгие условия. Смотрите этот код:

// case A
if($z>$x && $z<$y) {}
// case B
if($z>$x || $z<$y) {}

Результат:

$x | $y | $z | case A | case B
10   20    5    false     true
10   20   15     true     true
10   20   25    false     true

Всякий раз, когда случай A оценивается как истинный, случай B также делает. Но обратной ситуации не может быть. Поэтому, если вы поместите случай B первым в IF ELSE, он всегда вернет true до достижения случая A.
Фиксированный пример кода:

$valueEnlightOverBuy  = $_POST["enlightOverBuy"];
$valueEnlightUnderBuy = $_POST["enlightUnderBuy"];

// GREEN PRICE BUY
$fontColorBuy = "#FFF";

// user has provided price boundaries
if($valueEnlightOverBuy !== '' && $valueEnlightUnderSell !== '') {

   // satisfies both boundaries (violet, should be green ?)
   if($finalPriceBuyer >= $valueEnlightOverBuy && $finalPriceBuyer <= $valueEnlightUnderBuy) {
      $fontColorBuy = "#FF00FF";
   }
   // satisfies at least one boundary (green, should be violet ?)
   elseif($finalPriceBuyer >= $valueEnlightOverBuy || $finalPriceBuyer <= $valueEnlightUnderBuy) {
      $fontColorBuy = "#00FF00";
   }
   // outside the boundaries (wrong boundaries order) (red)
   else {
      $fontColorBuy = "#D00000";
   }
}

Инстинктивно у меня возникает ощущение, что вы действительно хотите, чтобы условие И было зеленым, а условие ИЛИ - фиолетовым, но я могу ошибаться в этом. И я должен указать, что красное условие срабатывает только в том случае, если границы установлены в неправильном порядке, хотя это представляется целесообразным.

По поводу обновления 2015-06-29:

В этом коде:

elseif(!empty($over) or !empty($under)) {
   if ($final >= $over or $final <= $under) {
      return $green;
   } 
   else {
      return $red; 
   }
}

В ваших примерах вы получаете $green, потому что $ over оценивается как ноль, поэтому любое положительное значение вернет зеленый. Вы должны только оценить значение, которое не является пустым.

elseif(!empty($over)) {
   return ($final >= $over) ? $green : $red;
}
elseif(!empty($under)) {
   return ($final <= $under) ? $green : $red;
}

Много вещей для решения здесь...

Похоже, вы могли бы использовать хорошее чтение на:

,

if (($finalPriceBuyer >= $valueEnlightOverBuy) or ($finalPriceBuyer <= $valueEnlightUnderBuy)) {
    $fontColorBuy = "#00FF00";
} else if (($finalPriceBuyer >= $valueEnlightOverBuy and $finalPriceBuyer <= $valueEnlightUnderBuy)) { ... }

Что еще более важно, быть ленивым и сухим. Если вы делаете одно и то же дважды, поместите его в функцию:

function getColor($value, $limitOver, $limitUnder, $colors){
    $underCheck = !is_numeric($limitUnder) || $value >= $limitUnder;
    $overCheck = !is_numeric($limitOver) || $value <= $limitOver;
    if ($underCheck && $overCheck) {
        // all valid bounds are satisfied
        return $colors['none'];
    } else if ($overCheck){
        // valid lower bound exists and is not satisfied 
        // and upper bound does not exist or is not valid or is satisfied
        return $colors['under'];
    } else if ($underCheck){
        // valid upper bound exists and is not satisfied 
        // and lower bound does not exist or is not valid or is satisfied
        return $colors['over'];
    } else {
        // both bounds exist and none of them are satisfied
        return $colors['both'];
    }
}

$colors = array (
    'both' => "#FF00FF",
    'over' => "#D00000",
    'under' => "#FFF",
    'none' => "#00FF00",
);

$colorBuy = getColor(
    $finalPriceBuyer,
    $_POST["enlightOverBuy"],
    $_POST["enlightUnderBuy"],
    $colors 
);

$colorLocal = getColor(
    $finalPriceSellerLocal,
    $_POST["enlightOverSloc"],
    $_POST["enlightUnderSloc"],
    $colors 
);

$colorInt = getColor(
    $finalPriceSellerInt,
    $_POST["enlightOverSellInt"];,
    $_POST["enlightUnderSellInt"],
    $colors 
);

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

ПРИМЕЧАНИЕ. Этот вопрос, скорее всего, следует перенести на сайт проверки кода.

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

  1. Используйте более короткие имена переменных
  2. Отступ пользователя
  3. Используйте встроенные функции PHP для упрощения, например, empty()
  4. Используйте функции, чтобы избавиться от повторения
  5. Группируйте похожие задачи в одном месте, например, получая значения $_POST переменные

Итак, сначала я перепишу ваш код, следуя этим советам:

// function to return color based on input
function getFontColor( $over, $under, $final ) {
    // colors
    $white  = '#fff';
    $green  = '#0f0';
    $violet = '#f0f';
    $red    = '#d00000';

    if ( !empty($over) and !empty($under) ) {
        if ( $final >= $over || $final <= $under ) return $green;
        if ( $final >= $over && $final <= $under ) return $violet;
        return $red;
    } else {
        return $white;
    }
}

// get all input variables at once
$over_buy  = $_POST['enlightOverBuy'];
$under_buy = $_POST['enlightUnderBuy'];
$over_loc  = $_POST['enlightOverSloc'];
$under_loc = $_POST['enlightUnderSloc'];
$over_int  = $_POST['enlightOverSellInt'];
$under_int = $_POST['enlightUnderSellInt'];

// now set the colors
$buy = getFontColor( $over_buy, $under_buy, $final_buy );
$loc = getFontColor( $over_loc, $under_loc, $final_loc );
$int = getFontColor( $over_int, $under_int, $final_int );

Как только мы это сделали, мы можем увидеть хотя бы одну проблему. getFontColor() функция выше никогда не вернется $violet потому что у вас есть OR заявление перед AND заявление. Чтобы исправить это, функция должна быть переписана как:

// function to return color based on input
function getFontColor( $over, $under, $final ) {
    // colors
    $white  = '#fff';
    $green  = '#0f0';
    $violet = '#f0f';
    $red    = '#d00000';

    if ( !empty($over) and !empty($under) ) {
        if ( $final >= $over && $final <= $under ) return $violet;
        if ( $final >= $over || $final <= $under ) return $green;
        return $red;
    } else {
        return $white;
    }
}

Однако, даже с этой версией, я все еще не уверен, что код делает то, что вы ожидаете. В любом случае, это должно быть проще для отладки, теперь, когда это проще и чище. Надеюсь это поможет!

Другие вопросы по тегам