如何在PHP中不使用'eval'创建动态IF语句?

时间:2018-05-09 16:10:45

标签: php

我想使用来自数据库的一些选项在PHP中构建一个IF语句。

假设我从DB获得这样的数组:

$db = [
    'number1' => [
        '<= 5',
        '&&'
    ],
    'number2' => [
        '> 200',
        '&&'
    ],
    'number3' => [
        '= 1',
        '||'
    ],
    'number3' => [
        '= 2',
        '||'
    ],
];

我想将其翻译成:

if ($data['number1'] <= 5 && 
    $data['number2'] > 200 &&
    ($data['number3'] == 1 || 
     $data['number3'] == 2
    )) {
    // do something
}

当然,我是通过做一个foreach并将数组的KEY放入$data['']数组来开始的。但是,我很不确定如何将逻辑运算符和其他所有内容放在适当的位置。

有人可以给我一个想法吗?

2 个答案:

答案 0 :(得分:5)

最好清理来自MySQL或任何用户生成的数据的数据,而不是使用eval()。对于您的情况,我建议将您的数据拆分为:

  • 操作
  • 操作数
  • 下一个逻辑

然后将其与现有的进行比较,然后使用它。首先,你可以这样做:

if ($operator == ">=")
  if ($operand >= $value)

或类似的东西递归 - 这是关键。希望这会有所帮助。

答案 1 :(得分:1)

嗯,听起来很奇怪,但我尝试过小代码示例: https://3v4l.org/h21gv

<?php

$arr = [
    'number1' => [
        'value' => 2,
        'comparator' => '<=',
        'compareTo' => 5,
        'next' => '&&'
    ],
    'number2' => [
        'value' => 230,
        'comparator' => '>',
        'compareTo' => 200,
        'next' => '&&'
    ],
    'number3' => [
        'value' => 1,
        'comparator' => '==',
        'compareTo' => 1,
        'next' => '||'
    ],
    'number3' => [
        'value' => 2,
        'comparator' => '==',
        'compareTo' => 2,
        'next' => '||'
    ],
];



function comparator(array $ar) {
    $i = 0;
    $m = count($ar);
    $last = true;
    foreach ($ar as $compare) {
        $i++;
        switch($compare['comparator']) {
            case '<=':
                $bool = $compare['value'] <= $compare['compareTo'];
                break;
            case '>':
                $bool = $compare['value'] > $compare['compareTo'];
                break;
            case '==':
                $bool = $compare['value'] == $compare['compareTo'];
                break;
        }
        if ($i < $m) {
            switch($compare['next']) {
            case '||':
                $last = $last || $bool;
                break;
            case '&&':
                $last = $last && $bool;
                break;
            }
        }
    }
    return $last;
}

var_dump(comparator($arr));