Итак, у меня есть некоторые данные, поступающие через POST из формы с большим количеством флажков, и я пытаюсь найти записи в базе данных, которые соответствуют проверенным параметрам. Существует четыре набора флажков, каждый из которых отправляется в виде массива. Каждый набор флажков представляет один столбец в базе данных, а значения из отмеченных полей хранятся в виде строки с разделителями-запятыми. Значения, которые я ищу, не обязательно будут последовательными, поэтому вместо одного значения LIKE%%, я думаю, мне нужно разбить его на серию операторов LIKE, объединенных с AND. Вот что у меня есть:
$query = "";
$i = 1;
$vals = [];
foreach($_POST["category"] as $val){
$query .= "category LIKE :cat".$i." AND ";
$vals[":cat".$i] = "%".$val."%";
$i++;
}
$i = 1;
foreach($_POST["player"] as $val){
$query .= "player LIKE :plyr".$i." AND ";
$vals[":plyr".$i] = "%".$val."%";
$i++;
}
$i = 1;
foreach($_POST["instrument"] as $val){
$query .= "instrument LIKE :inst".$i." AND ";
$vals[":inst".$i] = "%".$val."%";
$i++;
}
$i = 1;
foreach($_POST["material"] as $val){
$query .= "material LIKE :mat".$i." AND ";
$vals[":mat".$i] = "%".$val."%";
$i++;
}
$query = rtrim($query, " AND ");
$tubas = R::convertToBeans("tuba", R::getAll("SELECT * FROM tuba WHERE ".$query, $vals));
Похоже, что это работает в моем предварительном тестировании, но это лучший способ сделать это? Будет ли это безопасно от внедрения SQL?
Спасибо!
Пока вы используете параметризованные запросы (как и вы), вы должны быть защищены от внедрения SQL. Однако есть крайние случаи, когда использование PDO UTF-7 уязвимо (я думаю, что Redbean основан на PDO)
Я хотел бы изменить код на что-то вроде этого, сводит к минимуму беспорядок foreach.
$query = 'SELECT * FROM tuba';
$where = [];
$params = [];
$checkboxes = [
'category',
'player',
'instrument',
'material'
];
foreach ($checkboxes as $checkbox) {
if (!isset($_POST[$checkbox])) {
// no checkboxes of this type submitted, move on
continue;
}
foreach ($_POST[$checkbox] as $val) {
$where[] = $checkbox . ' LIKE ?';
$params[] = '%' . $val . '%';
}
}
$query .= ' WHERE ' . implode($where, ' AND ');
$tubas = R::convertToBeans('tuba', R::getAll($query, $params));
Других решений пока нет …