Dynamically select a comparison operator (>=, <=, etc) in a conditional?
if (foo >= bar) baz();
But let's say sometimes baz(); needs to be run when foo <= bar
, or foo == bar
... and let's say that this comparison opera开发者_Go百科tor is grabbed from, say, a db table, and placed into a variable: $param = ">="
.
Is there any way you could modify the first line to use $param
, besides a switch-case with multiple if statements?
In my code, baz();
spans about a whole bunch of lines, and would become an organizational nightmare were I to manage it by hand.
function lt($a, $b)
{
return $a < $b;
}
...
$relops = Array(
'<' => 'lt',
...
);
echo $relops['<'](2, 3);
I solved this using:
function doComparison($a, $operator, $b)
{
switch ($operator) {
case '<': return ($a < $b); break;
case '<=': return ($a <= $b); break;
case '=': return ($a == $b); break; // SQL way
case '==': return ($a == $b); break;
case '!=': return ($a != $b); break;
case '>=': return ($a >= $b); break;
case '>': return ($a > $b); break;
}
throw new Exception("The {$operator} operator does not exists", 1);
}
Use eval()?
$param = ">=";
eval ("if (foo $param bar ) baz();");
Read more on the documentation page for the eval function.
EDIT:
Indeed, as others have mentioned, if there are alternatives, they are almost always better than eval(). If used, it must be used with care.
elaborating on my comment:
function variableOpComparison($v1, $v2, $o) {
if ($o == '!=') return ($v1 != $v2); // could put this elsewhere...
$operators = str_split($o);
foreach($operators as $operator) {
switch ($operator) { // return will exit switch, foreach loop, function
case '>': if ($v1 > $v2) return true; else continue; break;
case '<': if ($v1 < $v2) return true; else continue; break;
case '=': if ($v1 == $v2) return true; else continue; break;
default: throw new Exception('Unrecognized operator ' . $operator . ' in ' . $o);
}
}
return false;
}
精彩评论