Reputation: 792
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.
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
Upvotes: 0
Views: 97
Reputation: 897
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
Upvotes: 1
Reputation: 781741
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.
Upvotes: 2
Reputation: 5202
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;
}
}
Upvotes: 2