Динамически созданное предложение WHERE PHP / MySQL

Я динамически генерирую часть WHERE в MySQL-запросе. Мой код ниже работает отлично до сих пор

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ: строки _GET все проверены в каком-либо месте в моем коде, но для того, чтобы этот код был доведен до разумной длины для этого вопроса, я разместил их непосредственно ниже. Для тех, кто хочет сделать что-то похожее на то, что я делаю, и использую мой код здесь в качестве базы, обязательно проверяйте свои строки, чтобы избежать инъекций mysql.

/* Loop through each column in the table */ for ( $i=0 ; $i<count($aColumns) ; $i++ ) { /* check if the column has been marked as searchable and that the param sent from the client contains data */ if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' ) { if ( $sWhere == "" ) { $sWhere = "WHERE "; } else { $sWhere .= " AND "; } /* RANGE FILTER CODE - This part is not important to this question but included for completenes */ $columnFilterValue = mysql_real_escape_string($_GET['sSearch_' . $i]); // check for values range $rangeSeparator = "~"; if (!empty($rangeSeparator) && strstr($columnFilterValue, $rangeSeparator)) { // get min and max $columnFilterRangeMatches = explode('~', $columnFilterValue); // get filter if (empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1])) $sWhere .= " 0 = 0 "; else if (!empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1])) $sWhere .= $aColumns[$i] . " BETWEEN '" . $columnFilterRangeMatches[0] . "' and '" . $columnFilterRangeMatches[1] . "' "; else if (empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1])) $sWhere .= $aColumns[$i] . " < '" . $columnFilterRangeMatches[1] . "' "; else if (!empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1])) $sWhere .= $aColumns[$i] . " > '" . $columnFilterRangeMatches[0] . "' "; } else { /* Begin building WHERE clause */ $sWhere = "WHERE ("; $aORs = array(); for ( $i=0 ; $i<count($aColumns) ; $i++ ) { if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' ) { $value = $_GET['sSearch_'.$i]; array_push($aORs, $aColumns[$i]." IN ($value)"); } } $sWhere .= implode(" OR ",$aORs); $sWhere .= ')'; } } } 

Теперь, что этот код делает это, он принимает строки разделенных запятыми значений, отправленных от клиента, и строит кластер WHERE на основе этих.

  • $ aColumns – это массив, содержащий столбцы в таблице

ПРИМЕР:-

Если параметры …

  • sSearch_1 содержит значение 1,3,5,6
  • sSearch_2 содержит значение 1,2,3
  • sSearch_4 подсчитывает значение 4,5,6
  • sSearch 6 имеет значение 7,8,9

Затем этот код генерирует следующее предложение WHERE:

  WHERE genre_id IN (1,3,5,6) OR instruments IN (1,2,3) OR emotions IN (4,5,6) OR ratings IN (7,8,9) 

Это прекрасно работает, но я хочу сделать динамику OR или AND также путем отправки другой строки, содержащей список OR и AND в правильном последовательном порядке.

так, например, если $ _GET ['filtertype'] = строка вроде этого: –

 OR,OR,AND 

то вместо вышесказанного он должен вернуться:

 WHERE genre_id IN (1,3,5,6) OR instruments IN (1,2,3) OR emotions IN (4,5,6) OR ratings IN (7,8,9) 

Как вы можете видеть в моем коде выше, я сейчас вставляю OR в мой массив через функцию implode. (Соответствующая часть кода повторяется ниже)

  $sWhere = "WHERE ("; $aORs = array(); for ( $i=0 ; $i<count($aColumns) ; $i++ ) { if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' ) { $value = $_GET['sSearch_'.$i]; array_push($aORs, $aColumns[$i]." IN ($value)"); } } $sWhere .= implode(" OR ",$aORs); $sWhere .= ')'; 

Как я могу изменить это, чтобы потом добавить правильные И ИЛИ ИЛИ на основе правильного цикла?

Вместо создания строки where я бы сначала создал массив с частями.

 $whereParts = array(); foreach($aColumns as $i => $column) { <logic goes here> $whereParts[] = 'genre_id IN (1,3,5,6)'; // sample :) } $where = 'WHERE ' . implode(' OR ', $whereParts); // note the spaces around OR 

Тогда легко заменить ' OR ' на ' AND '

Легко разрешить пользователям выбирать между AND и OR для всех частей, но не для того, чтобы делать это для каждого отдельного элемента. Это также логическая проблема. Когда пользователь указывает a OR b AND c , хотел ли он (a OR b) AND c или a OR (b AND c) ?