Написать этот пост меня побудили вопросы на эту тему на форуме php.ru. Итак, нужно при задании фильтров каких-то объектов (например, товаров) динамически формировать where. Сейчас я покажу, как это делается в построителях запросов известных мне фреймворкоа. Возьмём простой случай, когда все поля для фильтрации в одной таблице, и не требуется join-ов.
На самом деле, всё это очень просто сделать при помощи чудесной функции implode, предварительно накопив все условия в массиве:
function makeWhere($filters) {
global $db; // предполагается, что в глобальной переменной $db содержится
// правильно инициализированный объект mysqli
$wheres = []; // Замените на array(), если у вас php < 5.4
foreach ($filters as $key=>$value) {
// не забываем экранировать спец. символы SQL, а также заключить имя поля в обратные кавычки
// на случай совпадения последнего с зарезервированным словом SQL
$wheres[] = sprintf("`%s`='%s'", $key, $db->real_escape_string($value));
}
return implode(" and ", $wheres);
}
Как видно из комментариев, я предположил, что для работы с БД использовано расширение mysqli, и объект mysqli помещён в глобальную переменную $db. Конечно, глобальные переменные использовать не очень хорошо, но, по моему мнению, одна-две проблемы не представляют.
Используется эта функция так:
$sql = "select * from goods where" . makeWhere(["color"=>"красный", "season" => "Лето"]);
echo $sql;
/* Вывод:
select * from goods where `color`='красный' and `season`='Лето';
*/
Для использования других операций, таких, как >, < и т.п., необходимо дописать функцию makeWhere(), например так:
function makeWhere($filters) {
global $db; // предполагается, что в глобальной переменной $db содержится
// правильно инициализированный объект mysqli
$wheres = []; // Замените на array(), если у вас php < 5.4
foreach ($filters as $key=>$value) {
if (!is_array($value)) {
// не забываем экранировать спец. символы SQL, а также заключить имя поля в обратные кавычки
// на случай совпадения последнего с зарезервированным словом SQL
$wheres[] = sprintf("`%s`='%s'", $key, $db->real_escape_string($value));
}
else {
$wheres[] = sprintf"`%s` %s '%s'", $value[0], $value[1], $db->real_escape_string($value[2]));
}
}
return implode(" and ", $wheres);
}
Теперь вы можете использовать это так:
echo makeWhere(['color'=>'красный', ['price', "<", 123]]);