将 IF 条件与存储在变量中的比较运算符一起使用
Posted
技术标签:
【中文标题】将 IF 条件与存储在变量中的比较运算符一起使用【英文标题】:Using IF condtion with comparison operator stored in variable 【发布时间】:2013-08-13 10:05:29 【问题描述】:我有一套涉及比较运算符的规则。我想根据规则中存储的比较运算符的值做一些任务。我正在按照以下方式进行操作,但它不起作用。检查以下代码
if($benRules[$i]['amountCriteria']=='Greater than')
$comparison='>';
if($benRules[$i]['amountCriteria']=='Equal to')
$comparison='==';
if($benRules[$i]['amountCriteria']=='Less than')
$comparison='<';
if($value['1'].$comparison.$value[$i]['2'])
debug('Condtion checked');
问题是它总是检查条件是否为真。它需要 IF 条件内的整个参数为字符串,只要该字符串不为空,就会执行括号内的代码。 请在这里帮助我。
【问题讨论】:
首先,Equal to
是 ==
而不仅仅是一个 =
【参考方案1】:
如果没有某种魔法(create_function()
或 eval()
),这种构造是不可能的。
但是,您也可以使用闭包来实现您想要的;根据您要使用的运算符返回一个比较函数。您可以认为这是策略模式的廉价版本:
function getComparisonFunction($operator)
// comparison function is returned
return function($a, $b) use ($operator)
if ($operator == 'Greater than')
return $a > $b;
elseif ($operator == 'Equal to')
return $a == $b;
else // Less than
return $a < $b;
// get comparison function
$fn = getComparisonFunction($benRules[$i]['amountCriteria']);
// use comparison function
if ($fn($value['1'], $value[$i]['2']))
debug('Condtion checked');
【讨论】:
如果您运行的是 php 5.3 及更高版本,这可能是完美的解决方案。 @middaparka 是的,但是 5.3 已经存在了 4 年多 :)【参考方案2】:$str = "$result = (bool)($value['1'] $comparison $value[$i]['2']);";
eval($str);
if($result)
//true
您可以使用 eval(),但这也可以:
if($benRules[$i]['amountCriteria']=='Greater than')
$comparison = (bool)($value['1'] > $value[$i]['2']);
if($benRules[$i]['amountCriteria']=='Equal to')
$comparison = (bool)($value['1'] == $value[$i]['2']);
if($benRules[$i]['amountCriteria']=='Less than')
$comparison = (bool)($value['1'] < $value[$i]['2']);
if($comparison)
debug('Condtion checked');
编辑
这看起来更好
【讨论】:
代码形式为 if ($x) $y=true; 其他 $y=false; 是高度冗余的,只需写成 $y=(bool)$x;【参考方案3】:它总是评估为真,因为您只是评估一个字符串的存在(您不能在 PHP 中以这种方式构造逻辑语句)。
要实现您的目标,您需要像这样使用 switch 语句(您只需为每个潜在的比较运算符进行一对一匹配)......
switch ($comparison)
case '<': if($value['1'] < $value[$i]['2']) ... break;
case '==': if($value['1'] == $value[$i]['2']) ... break;
case '>': if($value['1'] > $value[$i]['2']) ... break;
...或使用eval 解析逻辑。如果使用 eval 方法似乎很容易,但正如 PHP 手册所承认的那样:
eval() 语言结构非常危险,因为它允许 执行任意 PHP 代码。因此不鼓励使用它。如果你 已经仔细验证除了使用这个没有其他选择 构造,特别注意不要传递任何用户提供的数据 在没有事先正确验证的情况下进入它。
因此,如果您不了解所涉及的风险,请坚持使用切换方法。也就是说,使用 eval 的基本解决方案类似于以下内容:
eval('return ' . $value['1'] . $comparison . $value[$i]['2'] . ';');
【讨论】:
在所有给出的答案中,我认为切换方法是最合适和最基本的。谢谢大家【参考方案4】:你可以使用eval
函数
if (eval('return '.$value['1'].$comparison.$value[$i]['2'].';'))
【讨论】:
eval() 语言结构非常危险,因为它允许执行任意 PHP 代码。请参阅文档php.net/manual/en/function.eval.php 刀也很危险,但你用它们,不是吗?如果合理地使用它,它是一个强大而有趣的工具。在这里,我们有一个从 switch 中获取的 $comparison,如果一个也转换为 $value[$i] 所以它必须只包含数字,这是一个 100% 安全的代码。【参考方案5】:if($benRules[$i]['amountCriteria']=='Greater than')
$comparison='>';
if($benRules[$i]['amountCriteria']=='Equal to')
$comparison='==';
if($benRules[$i]['amountCriteria']=='Less than')
$comparison='<';
eval('$bool = $value[\'1\']'.$comparison.'$value[$i][\'2\'];');
if($bool)
debug('Condtion checked');
【讨论】:
【参考方案6】:您的问题是您试图将字符串用作代码而不对其进行评估。你可以像这样使用create_function():
$sCondition = '<';
$mData0 = 4;
$mData1 = 5.5;
$fnCallback=create_function('$x, $y', 'return $x'.$sCondition.'$y;');
var_dump($fnCallback($mData0, $mData1)); // true
或者,有一个eval() 函数,但在你的情况下,直接返回似乎更有用。
【讨论】:
这是比使用 eval 更好的方法。 @middaparka 虽然,create_function()
的行为与 eval()
几乎相同 :)
是的。我们可以使用直接调用的唯一优点(无需创建临时变量)。以上是关于将 IF 条件与存储在变量中的比较运算符一起使用的主要内容,如果未能解决你的问题,请参考以下文章