Radical_Activity
Radical_Activity

Reputation: 2738

How to create dynamic IF statements without using 'eval' in PHP?

I would like to build an IF statement in PHP using some options that are coming from the Database.

Let's say I get an array like this from the DB:

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

I'd like to translate it into this:

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

Of course, I'd start it by doing a foreach and putting the KEYs of the array into the $data[''] array. However, I'm pretty unsure how can I put the logical operators and everything else in place.

Can anyone give me an idea please?

Upvotes: 0

Views: 99

Answers (2)

Eakethet
Eakethet

Reputation: 682

Well, sounds quite strange, but I've tried small code example: 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));

Upvotes: 1

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167192

It is always better to sanitize data that comes from MySQL or any user produced data, instead of using eval(). For your case, I would suggest having your data split into:

  • Operator
  • Operand
  • Next Logic

And then compare it with the existing ones and then use that. To start with, you can do:

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

Or something similar to build it recursively - this is the key. Hope this helps.

Upvotes: 5

Related Questions