Как создать оптимизированный запрос sql для множественной выпадающей фильтрации в php? - PullRequest
0 голосов
/ 07 мая 2020

Я новичок в php и работаю над проектом. Вначале было 2 фильтра, о которых я не особо беспокоился, когда писал запрос sql с 4 условиями. Но теперь у меня 8 разных раскрывающихся списков, и мне нужно написать оптимизированный sql для функций фильтра. Согласно условиям, которые должны быть записаны в счет, мне нужно написать 256 условий, что является наихудшей идеей.

Проблема в том, что нет обязательного поля для выбора для фильтрации. Это создает у меня больше проблем с применением различных подходов.

Есть ли другие альтернативы для решения этой проблемы? что было бы лучше всего для оптимизированного запроса.

Пример кода

if($_REQUEST['action']=='action_report'){
   $v1 = $_POST['v1'];
   $v2 = $_POST['v2'];

  if(!empty($v1) && !empty ($v2)){
     $sql = "SELECT * FROM TABLE WHERE v1=$v1 AND v2=$v2 AND action='action_report'";
  }elseif(!empty($v1) && empty($v2)){
     $sql = "SELECT * FROM TABLE WHERE v1=$v1 AND action='action_report'";
  }elseif(empty($v1) && !empty($v2)){
     $sql = "SELECT * FROM TABLE WHERE v2=$v2 AND action='action_report'";
  }elseif(empty($v1) && empty($v2)){
     $sql = "SELECT * FROM TABLE WHEREAND action='action_report'";
  }
}

1 Ответ

1 голос
/ 08 мая 2020

Код будет выглядеть следующим образом:

$sql = 'SELECT * FROM TABLE WHERE ';
$first = true;
foreach($_POST as $paramName => $value) {
    if ($first) {
        $sql .= "{$paramName}='{$value}'";
        $first = false;
        continue;
    }
    $sql .= " AND {$paramName}='{$value}'";
}

Поскольку $ _POST - это массив входящих переменных, вы можете go через него с помощью простого цикла foreach и присоединить его к SQL Строка запроса. Первый возможный параметр не будет нуждаться в операторе AND, поэтому вам придется обрабатывать его по-другому, поэтому переменная $first предназначена для.

Однако этот код имеет SQL уязвимости инъекций, поэтому лучше прикрепить имя параметра и значение в строке SQL, например:

$sql .= ' AND ' . mysqli_real_escape_string($connection, htmlspecialchars($paramName)) . "='" . mysqli_real_escape_string($connection, htmlspecialchars($value)) . "'";

Вы также получите пустые значения, которые вы не хотели бы присоединять к строке запроса SQL. Таким образом, окончательный код также должен обработать это, и после небольшого форматирования он будет выглядеть так:

$sql = 'SELECT * FROM TABLE WHERE ';
$first = true;
foreach($_POST as $paramName => $value) {
    $protectedParamName = mysqli_real_escape_string($connection, htmlspecialchars($paramName));
    $protectedValue = mysqli_real_escape_string($connection, htmlspecialchars($value));

    if (empty($value)) {
        continue;
    }

    if ($first) {
        $sql .= "{$protectedParamName}='{$protectedValue}'";
        $first = false;
        continue;
    }

    $sql .= " AND {$protectedParamName}='{$protectedValue}'";
}

В этом примере переменная $connection является объектом mysqli:

$connection = new mysqli(
    $dbConfig['host'],
    $dbConfig['user'],
    $dbConfig['password'],
    $dbConfig['databaseName'],
    $dbConfig['port']
);

foreach($_POST as $paramName => $value) проходит по всем значениям массива $ _POST, поэтому, если вы не хотите, чтобы некоторые поля использовались в запросе SQL, вы можете использовать фильтрацию черного списка, где вы указываете, если $ paramName находится в черном списке, то вы не будете прикреплять его к запросу SQL.

Например:

$blackList = [
    'action'
];
foreach($_POST as $paramName => $value) {
    if (in_array($paramName, $blackList)) {
        continue;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...