У меня проблема с фильтрацией таблицы SQL на основе ввода пользователем; Я не могу понять, как сделать его надежным для ряда входов, которые мне нужно приспособить.
По сути, пользовательский ввод, извлеченный из данных POST, используется для построения массива ($ filterarray) из таблицы SQL, содержащей параметры фильтра. Три столбца вытягиваются в массив из каждой выбранной строки таблицы; столбец 1 - строка, соответствующая имени столбца в SQL-таблице "finaloutputs", столбец 2 содержит оператор сравнения, столбец три - целочисленное значение. Таким образом, если возвращать последовательно в виде строки, каждая строка массива создает фильтр выбора, такой как "column_x <10" или "columm_y = 6". $ filterarray может иметь от 1 до 100+ строк, указывая на разные столбцы в окончательных выводах и используя любой оператор сравнения.
Такой запрос, как ниже, отлично работает:
$cf1 = wombats
$cf2 = "="
$cf3 = 0
$result = $DBLink->query("SELECT id FROM finaloutputs WHERE $cf1 $cf2 $cf3");
Но это просто инъекция одного набора переменных напрямую. Как я могу это сделать с помощью целого набора параметров? Код должен работать под оператором "и" -style; возвращаемые результаты должны удовлетворять всем фильтрам.
Кажется, что это должно быть возможно с комбинацией "foreach" и "array_filter" или "unset". Я не могу полностью определить, как на самом деле это сделать.
Например, что-то вроде этого (но это работает...):
//$filterarray contains in each row:
// string matching a column in finaloutputs table ('cf1')
// comparator ('cf2')
// value ('cf3')
$result = $DBLink->query("SELECT * FROM finaloutputs");
$resultarray = $result->fetch_assoc();
foreach ($filterarray as $row){
unset($resultarray[WHERE $row['cf1'] . $row['cf2'] . $row['cf3']]);
}
Я понимаю, что мой первый пример включает в себя на основе фильтра, который является истинным, второй пример исключается на основе истинного фильтра. Мне действительно все равно, что я использую - я могу поменять операторы сравнения в соответствии - я просто ищу эффективный код!
Заранее благодарю за любую помощь!
Почему бы не позволить SQL фильтровать данные, чтобы получить нужный результат?
Это должно работать:
$sql = 'select * FROM finaloutputs WHERE TRUE';
foreach ($filterarray as $row){
$sql .= ' AND ' . $row['cf1'] . $row['cf2'] . $row['cf3'];
}
$resultarray = $DBLink->query($sql)->fetch_assoc();