0

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

2
  • You need quotes around the regular expressions. You should be getting syntax errors. Commented Mar 4, 2019 at 20:37
  • Depending on just how complex the conditions are, you may benefit from using a rules engine for this Commented Mar 4, 2019 at 20:51

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

interesting, i didn't know i could use nested arrays that way, i will definitely try that, thank you !
2

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;
    }
}

1 Comment

thanks for the solution and the quick answer, will see what i can do with it !
1

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, e.g.:

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

1 Comment

thanks for the solution and the quick answer, will see what i can do with it once i tried Barmar's solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.