Уточнение результатов поиска на основе фильтров - PullRequest
0 голосов
/ 24 июля 2011

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

  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.

Ответы [ 2 ]

1 голос
/ 24 июля 2011

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

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

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

// ** 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...
}
1 голос
/ 24 июля 2011

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...