Выполнить запрос с условием или без
$query = !empty($_GET['box']) ?
"SELECT*FROM products WHERE categoryID IN (" . implode(',', $_GET['box']) . ")"
:
"SELECT*FROM products";
$result = $pdo->query($query);
$products = $result->fetchAll();
Всем привет! Есть три чекбокса, name которых передается в $_GET['box']. Хотела сделать параметризацию categoryID (categoryID=:categoryID) и передать методу execute() индексы для дальнейшего вывода запрашиваемых данных экран. У меня получилось это сделать в нижеприведенном скрипте, но с огромными костылями.
$arr = [];
$arr_products = [];
$products = [];
if(!empty($_GET['box'])) {
$arr = $_GET['box'];
}
else {
$products = [];
$result = $pdo->query("SELECT * FROM products");
$products = $result->fetchAll();
}
foreach ($arr as $key) {
$query= "SELECT * FROM products WHERE categoryID =:categoryID";
$result = $pdo->prepare($query);
$result -> execute(['categoryID' => $key]);
$arr_products = $products;
$products = array_merge($arr_products, $result->fetchAll());
}
Ответы (2 шт):
не именуйте параметры. В целом всегда надо следовать двум вариантам: либо вы передаете значения как параметры, либо вы проверяете их значения по списку или еще как-то их валидируете. Если у вас тут числовые идентификаторы, то потенциально вы можете удостовериться, что там именно числовые значения и подставить их в запрос. Либо же передать их не именованными, условно говоря:
$box = $_GET['box'] ?? [];
$sql = "SELECT id, title FROM products";
if($box) {
$cats = implode(',', array_map('intval', $box));
$sql .= " WHERE category_id IN ($cats)";
}
$st = $pdo->query($sql);
if($st){
$result = $st->fetchAll(PDO::FETCH_ASSOC);
}
либо
if($box){
$cats = array_map('intval', $box);
$q = implode(',', array_fill(0, count($box)-1, '?');
$sql .= "WHERE category_id IN ($q)";
}
$st = $pdo->prepare($sql)
и т.д.
Параметризовать запрос IN действительно получается грязновато, но в целом несложно:
- надо создать строку с плейсходерами вида ?,?,? по числу элементов в массиве
- а сам массив передать в execute
В общем виде код выглядит так
$in = str_repeat('?,', count($in_array) - 1) . '?';
$sql = "SELECT * FROM my_table WHERE my_value IN ($in)";
$stm = $db->prepare($sql);
$stm->execute($in_array);
$data = $stm->fetchAll();
Для это конкретной задачи можно также оптимизировать алгоритм
$arr = [];
$sql = "SELECT * FROM products";
if(!empty($_GET['box'])) {
$arr = $_GET['box'];
$in = str_repeat('?,', count($arr) - 1) . '?';
$sql .= " WHERE categoryID in ($in)"
}
$stmt = $pdo->prepare($query);
$stmt -> execute($arr);
$products = $stmt->fetchAll();