Параметризованный запрос с несколькими необязательными условиями поиска - PullRequest
2 голосов
/ 15 декабря 2010

У меня есть веб-приложение с большим количеством данных и функцией поиска / фильтрации с несколькими полями, такими как имя, статус, дата и т. Д. Я использовал параметризованные запросы, подобные этим, для обычных (не поисковых) запросов:

$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 возможных комбинаций поисковых терминов.

Ответы [ 2 ]

3 голосов
/ 15 декабря 2010

Вы уже защищены от внедрения SQL, так как вы используете mysqli_stmt_bind_params, который будет корректно работать для вас.

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

В противном случае ... это такой старый стиль спагетти ... но я люблю его: D

Довольно просто расширить ваш код для работы с неизвестным количеством параметров. Вы должны просто зациклить ваши параметры и в то же время 1. построить строку запроса с обозначением вопросительного знака и добавить свои параметры в массив, который вы будете передавать в maxdb_stmt_bind_param (ресурс $ stmt, строка $ 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);
1 голос
/ 15 декабря 2010

Рекомендую перейти на PDO.Он встроен в PHP подобно расширению mysqli, но имеет более чистый синтаксис и позволяет передавать значения параметров в виде массива, который можно легко создать динамически с любым количеством элементов.

...