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

Со стороны браузера пользователь будет вводить логический запрос, который может стать сложным, и я хочу преобразовать его в оператор 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?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я сделал следующее наблюдение из приведенного вами примера: все, что вам нужно сделать, это заменить токены, такие как 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-инъекциям.

Предупреждение: Это вызовет синтаксическую ошибку из-за отсутствия кавычек (WHERE skill=C++). Но если вы исправите это с помощью "skill='$token'", тогда он будет открыт для SQL-инъекции (например, ' union select pwd,0,0,0 from admins where '1).
Paul Spiegel 18.04.2019 13:15

Вы правы насчет пропущенных кавычек. Я просто взял ожидаемую строку из ответа. О SQL-инъекциях: в своем ответе я отметил опасность SQL-инъекций. Конечно, лучше всего было бы использовать подготовленные операторы, но они немного зависят от поставщика, и, поскольку в вопросе не упоминалась конкретная база данных, я не включил ее в свой ответ.

Arno Hilke 18.04.2019 15:15

Другие вопросы по теме