3

我有一套涉及比较运算符的规则。我想根据规则中存储的比较运算符的值做一些任务。我正在按照以下方式进行操作,但它不起作用。检查以下代码

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 条件内的整个参数为字符串,只要该字符串不为空,就会执行括号内的代码。请在这里帮助我。

4

6 回答 6

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()函数,但在您的情况下,直接返回似乎更有用。

于 2013-08-12T07:06:25.107 回答
5

它总是评估为真,因为您只是评估字符串的存在(您不能在 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 代码。因此不鼓励使用它。如果您已仔细验证除了使用此构造之外别无选择,请特别注意不要将任何用户提供的数据传入其中,而无需事先正确验证。

因此,如果您不了解所涉及的风险,请坚持使用 switch 方法。也就是说,使用 eval 的基本解决方案类似于以下内容:

eval('return ' . $value['1'] . $comparison . $value[$i]['2'] . ';');
于 2013-08-12T07:05:53.737 回答
1
$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');
            }

编辑

这看起来更好

于 2013-08-12T07:08:01.343 回答
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');
}
于 2013-08-12T07:12:21.593 回答
0
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');
}
于 2013-08-12T07:07:39.817 回答
0

您可以使用该eval功能

if (eval('return '.$value['1'].$comparison.$value[$i]['2'].';')){

}
于 2013-08-12T07:08:12.407 回答