Уточнение результатов поиска на основе фильтров

Я работаю над сайтом электронной коммерции. Показывая доступные мобильные телефоны, пользователь может фильтровать результаты следующими фильтрами:

  1. Имя бренда

    • Samsung
    • Nokia
    • HTC
    • (и многое другое)
  2. Ценовой диапазон

    • $ 100- $ 200
    • $ 200- $ 300
    • (и так далее)
  3. категория

    • Мобильные телефоны Android
    • Недорогие мобильные телефоны
    • Музыкальные телефоны
    • Телефоны 3G
    • … (и многое другое)

Я хочу использовать следующие параметры GET для генерации SQL-запроса, который будет выполняться каждый раз, когда применяется фильтр. Предположим, что текущий фильтр – Brand=Samsung тогда моя ссылка будет http://xyz.com/mobiles.php?brand=samsung

Для вышеуказанных фильтров PHP-код для генерации SQL-запроса выглядит следующим образом (используя множество операторов if/else и isset() ):

 $sql = "SELECT * from items "; if(isset($_GET['brand'])) { $sql = $sql . "where brand=".$_GET['brand']." "; /*similar statements*/ } 

Пожалуйста, не переходите к точности приведенных выше инструкций PHP, я не упомянул полный код. Наконец, у меня есть следующий SQL-код, который даст результат:

 SELECT * FROM ITEMS WHERE BRAND=SAMSUNG; 

Этот SQL-запрос приведет к соответствующим продуктам, и я буду показывать результаты на веб-странице соответственно. Пожалуйста, ответьте на следующие вопросы:

  1. После указанных выше фильтров (марка) предположим, что применяется также фильтр цен. Как я могу узнать, что фильтр brand уже существует, так что я могу перенаправить пользователя на

    http://xyz.com/mobiles.php?brand=samsung&priceMin=100&priceMax=200

    ВМЕСТО ПОСЛЕДУЮЩЕГО URL

    http://xyz.com/mobiles.php?priceMin=100&priceMax=200

    т.е. как я могу просто добавить ценовые критерии к URL?

  2. Существует ли программное обеспечение / библиотека / код для фильтрации продуктов?

  3. Есть ли лучший способ отфильтровать продукты или лучший способ генерировать SQL, чем метод, упомянутый выше?

Я использую PHP, MySQL, Apache на компьютере с Windows.

Позвольте мне ответить на ваш вопрос

1. Если пользователь уже фильтрует конкретную марку, просто сохраните бренд в переменной сеанса

 $sql = "SELECT * from items "; if(isset($_GET['brand'])) { $_SESSION['brand'] = $_GET['brand']; //your code } 

Затем в следующем запросе проверьте наличие этой переменной

 if($_SESSION['brand']) { $url = $_SERVER['PHP_SELF'] . '?brand=' . $_SESSION['brand']; header( 'Location:' . $url ); exit; } 

2.Я не знал о ..

3.Вы можете построить лучший запрос, добавив WHERE 1=1

 $query = "SELECT * FROM items WHERE 1=1"; if($_GET['brand') { $query .= " AND brand={$_GET['brand'}"; } //another condition perhaps 

У меня возникнет соблазн построить таблицу отправки, которая вызывает функцию для каждого параметра запроса. Это позволяет создать белый список безопасных параметров запроса. Я бы также использовал параметризованные операторы, чтобы помочь защитить от SQL-инъекции (то, что ваш существующий код не защищен от). PDO упрощает использование параметризованных операторов.

Создание отдельной функции для каждого параметра запроса может показаться ненужным сначала, но это означает, что вы можете поместить все свои условия в отдельный файл, тем самым сохраняя основную функцию запроса. Это также облегчает реализацию будущих улучшений.

Ниже приведен пример нестандартного примера. Он не предназначен для того, чтобы быть готовым вырезать и вставлять в приложение. Это просто дать вам представление о том, что я имею в виду. В реальном приложении, помимо прочего, вам нужно включить проверку ошибок и, скорее всего, переместить соединение с базой данных в другом месте.

 // ** query_params.php ** function query_brand () { return "brand = ?"; } function query_price () { return "price BETWEEN ? AND ?"; } function query_category () { return "category = ?"; } // ** product_search.php ** function search () { // Build a test GET array. $_GET = array( 'brand' => 'HTC', 'price' => array(100, 200), 'category' => 'Android Mobiles' ); // Build a dispatch table of safe query parameters. $dispatch = array( 'brand' => 'query_brand', 'price' => 'query_price', 'category' => 'query_category' ); // An array to hold the conditions. $cond = array(); // An array to hold the bind values. $bind = array(); foreach ( $_GET as $param => $value ) { if( isset($dispatch[$param]) ) { $cond[] = call_user_func( $dispatch[$param] ); $bind[] = $value; } } $sql = "SELECT item, brand, price, category " . "FROM products"; if( count($cond) ) { // Combine the conditions into a string. $where = implode( ' OR ', $cond ); $sql .= " WHERE $where"; } // Use PDO to connect to the database. This should // probably be done somewhere else. $dbh = new PDO( "mysql:host=localhost;dbname=$dbname", $user, $pass, ); // Prepare the SQL statement. $stmt = $dbh->prepare( $sql ); // Execute the statement, passing the values to be // bound to the parameter placeholders. $stmt->execute( $bind ); // Fetch and return results... }