phpquery-parser

How to parse a simple search query with PHP?


So I like to have a simple (custom) search query. That exists of two things a PASSWORD and a DATE. So I can construct something like: DATE BEFORE "01-11-2022 14:00" AND (PASSWORD IS "welcome" OR PASSWORD IS "1234").

My thoughts about parsing this is first getting an array like:

[
    {
        Condition: "DATE BEFORE \"01-11-2022 14:00\"",
        Operator: "AND"
    },
    [
        {
            Condition: "PASSWORD IS \"welcome\"",
            Operator: "OR"
        },
        {
            Condition: "PASSWORD IS \"1234\""
        }
    ]
]

Then walk through the conditions and parse them separatly by using eval.

$condition = str_replace('PASSWORD', $_GET['PASSWORD'], $condition);
$condition = str_replace('IS NOT', '!=', $condition);
$condition = str_replace('IS', '=', $condition);
$result = eval($condition);
  1. If the condition has no operator; STOP
  2. If the result is FALSE and the operator is AND; STOP
  3. Else continue evaluating the next condition.

So if the password is 1234 and date is before this would result in.

[
    TRUE (AND)
    [
        FALSE (OR)
        TRUE
    ]
]
----
[
    TRUE (AND)
    TRUE
]
----
TRUE

But I am already stuck at parsing the search string, because the parentheses can be nested like ((PASSWORD IS "welcome" OR PASSWORD IS "1234") AND DATE BEFORE "01-11-2022") OR PASSWORD = "admin".

So hence the question. How can you parse this simple search query?


Solution

  • Why not formulate the conditions in a PHP-compliant way? Approach:

    $query = 'DATE < "2022-11-01 14:00" AND (PASSWORD == "welcome" OR PASSWORD == "1234")';
    
    $query = str_replace(['DATE','PASSWORD'],['"2022-10-31 13:00"','"1234"'],$query);
    $isOk = eval('return '.$query.';');
    var_dump($isOk);
    

    Since eval() is dangerous, the replacements for DATE and PASSWORD must be checked carefully.