将 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 条件与存储在变量中的比较运算符一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SQL 比较条件 ANY/SOME 与 DATATYPE Char 一起使用

1.7比较与测试

具有多个条件的 if 语句

变量变量如何与++运算符一起使用?

(24)Poweshell中的if条件判断

thinkphp <if> 标签比较中的 或者 用 OR ,那么 且 是否用 AND 或者是啥?