Я динамически генерирую часть 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 на основе этих.
ПРИМЕР:-
Если параметры …
Затем этот код генерирует следующее предложение 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)
?