У меня есть веб-приложение с большим количеством данных и функция поиска / фильтрации с несколькими полями, такими как имя, статус, дата и т. Д. Я использую параметризованные запросы, подобные этому для регулярных (не-поисковых) запросов:
$id = $_POST['itemID']; $db = mysqli_connect($host, $username, $password, $database); $sql_query = "SELECT * FROM tbl_data WHERE ID = ?"; $stmt_query = mysqli_prepare($db, $sql_query); mysqli_stmt_bind_params($stmt_query, "i", $id); mysqli_stmt_execute($stmt_query); //and so on..
Как я могу защитить SQL-инъекцию с несколькими необязательными параметрами? Может быть до 10 отдельных параметров, которые могут быть или не могут быть установлены.
Редактировать, поскольку вопрос кажется неясным :
Мой пример был с одним параметром, который не является обязательным. Я знаю, что это защищает от SQL-инъекции. Как мне это сделать с 10 параметрами, где один или несколько могут быть установлены одновременно? Например, такой запрос:
SELECT * FROM tbl_data WHERE NAME = ? AND STATUS = ? AND DATE = ? AND PARAM4 = ? AND PARAM5 = ?
где пользователь только хочет искать по имени и дате. Как мне сделать привязку? Не рекомендуется проверять каждую из 100 возможных комбинаций поисковых терминов.
Вы уже защищены от SQL-инъекции, так как используете mysqli_stmt_bind_params, который будет автоматически удаляться для вас.
Редактировать. Вы можете переключиться на некоторые базы данных, чтобы иметь чистый и красивый код.
В противном случае … это такой старый стиль спагетти … но мне это нравится: D
Достаточно просто расширить свой код для работы с неизвестным количеством параметров. Вы должны просто зациклиться на своих параметрах и в то же время 1. построить строку запроса с помощью знака вопросительного знака и добавить свои параметры в массив, который вы передадите в maxdb_stmt_bind_param (ресурс $ stmt, string $ types, array & $ var).
Так было бы так. Он предполагает, что есть хотя бы один параметр (только тривиально, чтобы этого избежать).
$sql = "SELECT * FROM tbl_data WHERE "; $and = ''; $types = ''; $parameters = array(); foreach($_POST as $k => $v) { // check that $k is on your whitelist, if not, skip to the next item $sql .= "$and $k = ?"; $and = " AND "; $parameters[] = $v; $types .= 's'; } $stmt_query = mysqli_prepare($db, $sql); mysqli_stmt_bind_params($stmt_query, $types, $parameters);
Я рекомендую переключиться на PDO. Он встроен в PHP, как расширение mysqli, но имеет более чистый синтаксис и позволяет передавать ваши значения параметров в виде массива, которые вы можете легко построить динамически с таким количеством элементов, сколько необходимо.