简体   繁体   中英

PHP & nested conditions

in PHP (and even other languages but in the present case this is more for PHP), i often end up sometimes having to code long conditions such as the example below:

i have a code with many conditions and i want to display a different result based on certain conditions.

  • if something is RED and the other thing is RED, then print X,
  • if something is RED but the other thing is BLACK, then print Y
  • if something RED and the other thing is RED but a third thing is blue, then print X
  • & so on

is there a way to properly handle this by using some kind of data structure/configuration array/matrix/whatever ? that is, storing these "conditions" and "results" properly in some kind of configuration array or other ?

instead of having to code nested conditions that can be tricky to support afterwards like this very small example but in a much bigger scale

if (preg_match(/something/, $string) {
  $result = 'GREEN';
} elseif (preg_match(/something/, $string) {
  $result = 'RED';
} else {
  if (something else) {
    $result = 'GREEN';
  } else {
    if (something OR something) {
       $result = 'AMBER';
    } else {
       $result = 'GREEN';
    }
  }
}

or is it the only way of handling this ? maybe with a single

if (something and something or something) {

} elseif (something and something and something) {

} elseif (something and something or something and something) {

} etc

thank you for your help

i'm coding an app that should display a different "status" for a certain data depending on many different data (other attributes of this data), and i'd like to avoid having unreadable code

For the purposes of the answer below I'm assuming you're coding OO PHP .

One variable

When I have one variable that determines the outcome, if the variable is boolean or close to being boolean (meaning it can only either be one or two different values), is to use an if() statement like you have. If the variable can be a variety of (known) values, like your colours example, I use a switch() function.

Two or more variables

If I have two variables that determine the outcome, for instance colour and size, I first use a switch() , then for each switch, I use a method that contains another switch() .

It may be more verbose, but it is so much easier to keep track of in the long run. Below is a simplified example of the logic.

switch ($colour) {
case 'red':
    red_handler($size);
    break;

case 'green':
    green_handler($size);
    break;

case 'blue':
    blue_handler($size);
    break;
}

/** We already know the first variable value is red */
function red_handler($size)
{
    switch ($size) {
    case 'small':
        echo "my fruit is a cherry";
        break;

    case 'medium':
        echo "my fruit is an apple";
        break;

    case 'large':
        echo "my fruit is a watermelon";
        break;
    }
}

You can use nested arrays:

$conditions = [
    '/something1/' => [
        '/something2/' => "X"
    ],
    'thing3' => [
        '/thing3/' => 'Y',
        '/thing4/' => 'Z'
    ]
];
$matched = false;
foreach ($conditions as $key1 => $val1) {
    if (preg_match($key1, $string)) {
        if (is_array($val1)) {
            foreach ($val1 as $key2 => $val2) {
                if (preg_match($key2, $string)) {
                    $result = $val2;
                    $matched = true;
                    break;
                }
            }
        } else {
            $result = $val1;
            $matched = true;
        }
    }
    if ($matched) {
        break;
    }
}
if (!$matched) {
    $result = 'default';
}

To allow arbitrary levels of nesting you could turn this into a recursive function.

In a similar vein to @dearsina i'd tend to separate it out into functions for this kind of thing, for example if you know there are lots of cases where it could return the same value, eg:

if(isGreen($string)) return 'GREEN';
else if (isRed($string)) return 'RED';

function isGreen($string) {
    if(cond1)return true;
    if(cond2 && cond3)return true;
    if(cond4 || cond 5)return true;
    return false;
}

function isRed($string) {
    if(cond6)return true;
    if(cond1 && cond7)return true;
    if(cond2 || cond 8)return true;
    return false;
}

we do sometimes use the style you've suggested...

if (something and something or something) {

} else if (something and something and something) {

but you can quickly end up back in the same problems of readability and maintenance issues

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM