@HasBenBlahBlag

Как составить логику для фильтра?

Есть интернет-магазин. И есть фильтр по каталогу: тип, страна, производитель, назначение, текстура, цена. Логика сложная щас попробую объяснить:

Если чел выбрал тип, то показываем товар по типу, если тип и страну то показываем по типу и стране, так же чел может выбрать только страну и цену, или производителя и цену, или производителя и страну. А может и просто цену.

Как такое можно реализовать? Понимаю вопрос странный, но уже второй день бьюсь с конструкциями if else и не выходит так как нужно.

Заранее спасибо.
  • Вопрос задан
  • 2948 просмотров
Пригласить эксперта
Ответы на вопрос 3
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Вариант 1 - в php собираете запрос из кусков
$where = array();
if (isset($_GET['manufacturer']))
    $where[] = "`manufacturer` = '".$mysqli->escape_string($_GET['manufacturer'])."'";
if (isset($_GET['madeIn']))
    $where[] = "`madeIn` = '".$mysqli->escape_string($_GET['madeIn'])."'";
$query = "SELECT * FROM `table` WHERE ".implode(" AND ", $where);
$result = $mysqli->query($query);

Вариант 2 - запрос с двойным условием
$manufacturer = '';
$byManufacturer = 0;
$madeIn = '';
$byMadeIn = 0;
if (isset($_GET['manufacturer'])) {
    $manufacturer = $_GET['manufacturer'];
    $byManufacturer = 1;
}
if (isset($_GET['madeIn'])) {
    $madeIn = $_GET['madeIn']";
    $byMadeIn = 1;
}
$query = $mysqli->prepare(
    "SELECT * FROM `table` ".
        "WHERE (? = 0 OR `manufacturer` = ?) ".
            "AND (? = 0 OR `madeIn` = ?)");
$query->bind_param('isis', $byManufacturer, $manufacturer, $byMadeIn, $madeIn);
$query->execute();
Ответ написан
Не совсем понятно, но думаю должно быть у вас что-то такое
$rgFilters = $_POST['filters'];
$rgSql = [];
foreach($rgFilters as $k=>$v){
    switch($k){
        case 'type':
            $rgSql[] = 'type_id = ' . $v;
            break;
            
        case 'country':
            $rgSql[] = 'country_id = ' . $v;
            break;
            
        case 'price_from':
            $rgSql[] = 'price > ' . $v;
            break;
        
        case 'price_to':
            $rgSql[] = 'price > ' . $v;
            break;
        
        case 'manufacturer':
            $rgSql[] = 'manufacturer_id = ' .$v;
            break;
    }
}

/**
 * Для учета всех параметров
 */
$query = 'SELECT * FROM `products` ' . implode(' AND ', $rgSql);
    
/**
 * Для получение товаров с совпадением хотябы одного параметра
 * Конечно бредовая ситуация, ну а вдруг
 */
$query = 'SELECT * FROM `products` ' . implode(' OR ', $rgSql);


При использовании какой либо ORM читайте доки как строить запросы.
Ответ написан
Комментировать
@xAockd
$sort_types  = ['type', 'country', 'price'];
$sign_for_query = ['type' => '=', 'price' => '>', 'country' => '='];
$sql = '';
$data = $_POST['filters'];
foreach($sort_types as $type) {
			if(array_key_exists($type, $data)) {
				$sql[] = '`'.$type . '` ' . $sign_for_query[$type] . ' ' .$data[$type];
		   }
}

Получается массив с запросами. В SQL всё переводим как-то так
implode(' AND ', $sql)

Update:
$specials = ['price' => 'min({val})'];
foreach($sort_types as $type) {
			if(array_key_exists($type, $data)) {
                                 if(array_key_exists($type, $specials)) {
                                      $sql[] = str_replace('{val}', $el, $specials[$el]);
                                  } else {
				     $sql[] = '`'.$type . '` ' . $sign_for_query[$type] . ' ' .$data[$type];
                                }
		   }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы