Добавление термина к каждому элементу логического запроса в PHP (reg exp?) - PullRequest
0 голосов
/ 09 апреля 2019

На стороне браузера пользователь будет вводить логический запрос, который может усложниться, который я хочу перевести в оператор SQL SELECT.

Пользователь будет вводить текстовую строку вместе слинии a AND ((b OR c) OR (not d)).Как я уже сказал, это произвольная текстовая строка, содержащая логическое выражение.

Это для программного рекрутера, поэтому a, b, c, d и т. Д. Будут такими навыками, как C, C ++, UML, Pythonи т. д., чтобы предыдущий пример мог фактически прочитать C++ AND ((UML OR Python) OR (not Perl)).

К чему я хочу расширить (в данном случае) SELECT * FROM candidates WHERE skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)).

Я могу добавить оператор SELECT, но как мне перевести (например) C++ AND ((UML OR Python) OR (not Perl)) в skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)) и сделать это для любого произвольного логического выражения с любым количеством скобок в PHP?

1 Ответ

1 голос
/ 09 апреля 2019

Я сделал следующее наблюдение на примере, который вы разместили: все, что вы хотите сделать, - это заменить токены, например C++, токеном формы skill=C++, остальная часть запроса не изменится.Если это не всегда так, вам может потребоваться более сложное решение, но если этого достаточно для вас, должно работать следующее:

$expr = 'C++ AND ((UML OR Python) OR (not Perl))';

// remove tokens that will not be replaced, here `(`, `)`, and `not`
$trimmed = str_replace(['(', ')', 'not'], ['', '', ''], $expr);

// split string based on the keywords `AND` and `OR` (case insensitive)
// keywords will also not be replaced
$tokens = preg_split('/AND|OR/i', $trimmed);

// create replacement tokens without leading/trailing whitespace
$replacementTokens = [];
foreach ($tokens as &$token) {
    $token = trim($token);
    $replacementTokens[] = "skill=$token";
}

// replace tokens and construct the query
$where = str_replace($tokens, $replacementTokens, $expr);
$query = "SELECT * FROM candidates WHERE $where";

Как уже говорилось, это решение может не работать, если вам нужно более сложное поведение,Вам также может понадобиться расширить списки ключевых слов.Но для предоставленного вами простого варианта использования он избавляет от необходимости фактически анализировать запрос.

В заключение отметим, что вы дезинфицируете свои пользовательские входные данные, поэтому вы не подвержены SQL-инъекциям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...