Множественные фильтры, которые необязательны для таблицы MySQL - PullRequest
0 голосов
/ 09 мая 2020

Итак, у меня есть таблица базы данных со следующими столбцами:

ID
Foo
Bar
Gux

Foo может содержать значения [a, b, c], Bar [1, 2, 3] и Gux [x, y, z].

В моем интерфейсе есть поле выбора HTML для фильтрации по Foo, Bar и Gux. Проблема в том, что пользователь может фильтровать по одному, двум или трем параметрам в случайном порядке.

Это дает мне проблему, чтобы сделать эффективный SQL -запрос и bind_param.

I можно было сделать что-то вроде этого:

//Pseudo code

$sql = "";

if (isset($_GET['foo'])) {
    $sql = "SELECT * FROM ... WHERE foo=?";
}
if (isset($_GET['bar'])) {
    $sql = "SELECT * FROM ... WHERE bar=?";
}
if (isset($_GET['gux'])) {
    $sql = "SELECT * FROM ... WHERE gux=?";
}

Но что, если использовать выбранные foo и bar? Также было бы очень уродливо и сложно реализовать bind_params.

Идеально было бы подстановочным знаком, поэтому я мог бы сделать

//Pseudo code

$sql = "SELECT * FROM ... WHERE foo=* AND bar=* AND gux=*";

и заменить * фактическим значением только тогда, когда выбран фильтр для этого столбца. Но это не поддерживается для целых чисел.

Другой вариант, о котором я подумал, - это сделать следующее:

//Pseudo code

$sql = "SELECT * FROM ... WHERE foo=filter1 OR bar=filter2 OR gux=filter3";

И программно заменить OR на AND, когда значение для этого столбца выбран. Это также решит проблему с bind_param. Но я не знаю, лучший ли это способ сделать это.

1 Ответ

2 голосов
/ 09 мая 2020

Как упоминал RiggsFolly, строить предложение WHERE динамически. В этом коде предполагается, что будет как минимум 1 вариант (в противном случае также условно добавьте WHERE.)

Каждая часть добавляется в список вместе с соответствующим массивом привязки, это показывает данные, вам нужно будет добавить собственно часть API для базы данных. Часть WHERE объединяется с использованием implode() с AND в качестве клея ...

$binds = [];
$where = [];
$types = '';
if (isset($_GET['foo'])) {
    $where[] = "foo=?";
    $binds[] = $_GET['foo'];
    $types .= "s";
}
if (isset($_GET['bar'])) {
    $where[] = "bar=?";
    $binds[] = $_GET['bar'];
    $types .= "s";
}
if (isset($_GET['gux'])) {
    $where[] = "gux=?";
    $binds[] = $_GET['gux'];
    $types .= "i";
}

$sql = "SELECT * FROM ... WHERE " . implode(" AND ", $where);

echo $sql.PHP_EOL;
print_r($binds);

с 1 в значении foo дает ...

SELECT * FROM ... WHERE foo=?
Array
(
    [0] => 1
)

Затем используйте типы и привязки в bind_param() ...

bind_param($types, ...$binds);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...