skip to Main Content

I have a PHP array like so:

$booleans = array(true, '||', false, '&&', true, '||', false);

Now I would now like to convert this array to a condition, e.g.:

if(true || false && true || false){

     // Do something

}
else{

    // Do something else

}

Preferably, for security reasons, I want to avoid using eval.

Is this possible? If so, what is the most efficient way to do it?

3

Answers


  1. Seems a bit weird to me why you’d want to do that. But for complex repetitive validations you may use functions.

    Like so:

    function validate($params) {
        return true || false && true || false; // Maybe you'd want to use $params in there at some point?
    }
    

    Then you can use it in an if statement

    if(validate($myParam)){
         // Do something
    }
    else{
        // Do something else
    }
    

    I still don’t understand WHY you’d want what you have shown in your question but I think you may be able to accomplish what you want with a similar type of function(s).

    Login or Signup to reply.
  2. This is not a finite solution for all operations and precedence, but a direction on how you may resolve it. You can refer to Shunting yard algorithm
    .

    $validateExpression = function (array $expression): bool {
        $allowedOperators = ['&&', '||'];
        $values = [];
        $operators = [];
        foreach ($expression as $expr) {
            if (is_bool($expr)) {
                $values[] = $expr;
                continue;
            }
            if (in_array($expr, $allowedOperators)) {
                $operators[] = $expr;
                continue;
            }
            throw new InvalidArgumentException('Invalid expression');
        }
    
        while($operators) {
            $a = array_shift($values);
            $b = array_shift($operators);
            $c = array_shift($values);
            array_unshift($values, match($b) {
                '&&' => $a && $c,
                '||' => $a || $c,
            });
        }
    
        return reset($values);
    };
    
    var_dump($validateExpression([true, '||', false, '&&', true, '||', false]));
    var_dump(true || false && true || false);
    

    Output

    bool(true)
    bool(true)
    
    Login or Signup to reply.
  3. Make sure that array is well-formatted and you can use this code:

    <?php
    
    function parseArray(array $booleans): bool
    {
        $result = false;
    
        for ($i = 0; $i < count($booleans); $i += 2) {
            if ($i + 1 === count($booleans) || $booleans[$i + 1] === '||') {
                $result = $result || $booleans[$i];
    
                continue;
            }
    
            $andResult = $booleans[$i];
            while ($booleans[$i + 1] === '&&') {
                $i += 2;
    
                $andResult = $andResult && $booleans[$i];
    
                if ($i + 1 === count($booleans)) {
                    break;
                }
            }
    
            $result = $result || $andResult;
        }
    
        return $result;
    }
    
    var_dump(parseArray([false]));
    var_dump(parseArray([true]));
    var_dump(parseArray([true, '&&', false]));
    var_dump(parseArray([true, '&&', true]));
    var_dump(parseArray([true, '||', false]));
    var_dump(parseArray([false, '||', false]));
    var_dump(parseArray([false, '||', false, '&&', true, '||', false]));
    var_dump(parseArray([true, '||', false, '&&', true, '||', false]));
    

    First of all collapse all && because they have higher priority, then calculate all ||

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search