Несколько критериев поиска в PHP и MySql

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

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

Пользователи, скорее всего, не будут использовать все доступные входные данные, потому что чаще всего это не даст им никаких результатов.

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

Вот мой код до сих пор.

<?php

      $dbName = "F:/Domains/autodeal/autodeal.co.za/wwwroot/newsite/db/savvyautoweb.mdb";

      // Throws an error if the database cannot be found
      if (!file_exists($dbName)) {
        die("Could not find database file.");
      }

      // Connects to the database
      // Assumes there is no username or password
      $conn = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$dbName", '', '');

      if (isset($_REQUEST['submit'])) {
        $searchMake = addslashes($_POST['makeSelection']);
        $searchModel = addslashes($_POST['modelSelection']);
        $searchBranch = addslashes($_POST['branchSelection']);
        $searchYear = addslashes($_POST['yearSelection']);
        $minPrice = addslashes($_POST['minPriceSelection']);
        $maxPrice = addslashes($_POST['maxPriceSelection']);

        $sql = "SELECT Id, Make, Model, Year, Price, SpecialPrice, Branch, StockNO FROM Vehicle WHERE Price BETWEEN $minPrice AND $maxPrice AND Make LIKE '$searchMake' AND Model LIKE '$searchModel' AND Year LIKE '$searchYear' AND Branch LIKE '$searchBranch'";
        $rs = odbc_exec($conn, $sql);


      //} else {
        //$sql = "SELECT Id, Make, Model, Year, Price, SpecialPrice, Branch, StockNO FROM Vehicle ORDER BY Make";
        //$rs = odbc_exec($conn, $sql) or die (odbc_errormsg());

      }   



          echo "\t" . "<tr>\n";

              echo "\t" . "<th>Make</th><th>Model</th><th>Year</th><th>Price</th><th>Special Price</th><th>Location</th><th>Stock Number</th>" . "\n";

                  while (odbc_fetch_row($rs)) { 
                      $id = odbc_result($rs, Id);
                      $make = odbc_result($rs, Make);
                      $model = odbc_result($rs, Model);
                      $year = odbc_result($rs, Year);
                      $price = odbc_result($rs, Price);
                      $specialPrice = odbc_result($rs, SpecialPrice);
                      $branch = odbc_result($rs, Branch);
                      $stockNo = odbc_result($rs, StockNO);

                          echo "\t" . "<tr>\n";
                              echo "\t\t" . "<td>" . $make . "</td><td><a href=/newsite/selected-vehicles?Id=$id>" . $model . "</a></td><td>" . $year . "</td><td>" . $price . "</td><td>" . $specialPrice . "</td><td>" . $branch . "</td><td>" . $stockNo . "</td>\n";

                          echo "\t" . "</tr>\n";
                  }

      odbc_free_result($rs);
      odbc_close($conn);

      // This message is displayed if the query has an error in it
      if (!$rs) {
          exit("There is an error in the SQL!");
      }

  ?>

Как сделать, чтобы сообщение появилось?

РЕДАКТИРОВАТЬ: теперь запрос работает и отображает полученные результаты на основе сделанных выборов, но все выборы должны быть сделаны, иначе он ничего не отображает.

Пожалуйста, имейте в виду, что марка ДОЛЖНА быть выбрана. Это не могут быть все бренды. В противном случае вы можете просто просмотреть всю таблицу.

Как я могу структурировать приведенный выше запрос, чтобы в качестве допустимых вариантов были «все модели», «любая ветвь», «любой год» и «любая цена»?


person Deon    schedule 03.04.2014    source источник
comment
добавляет слеши?!? пожалуйста, наймите кого-нибудь.   -  person    schedule 04.04.2014
comment
если вы распечатаете этот оператор sql, что он скажет? echo "\n\n$sql\n\n"; . Можете ли вы добавить это к своему вопросу?   -  person bobkingof12vs    schedule 04.04.2014
comment
@bobkingof12vs Я отредактировал вопрос.   -  person Deon    schedule 04.04.2014
comment
@ deon4110 deon4110 Я больше надеялся увидеть, что установлено для $sql после того, как вы создадите свой запрос. Можете ли вы опубликовать результат echo "\n\n$sql\n\n" при запуске кода? Извините, если я не понимаю   -  person bobkingof12vs    schedule 04.04.2014
comment
Вот что печатается: SELECT Id, Make, Model, Year, Price, SpecialPrice, Branch, StockNO FROM Vehicle WHERE Price >= 50000 AND Price <= 900000 AND Make LIKE 'searchMake' AND Model LIKE 'searchModel' AND Branch LIKE 'EAST_RAND' AND Year LIKE '2011'   -  person Deon    schedule 04.04.2014
comment
Пожалуйста, смотрите мой отредактированный вопрос.   -  person Deon    schedule 04.04.2014


Ответы (1)


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

SELECT Id, Make, Model, Year, Price, SpecialPrice, Branch, StockNO
FROM Vehicle
WHERE 
    Price >= $minPrice AND
    Price <= $maxPrice AND
    Make LIKE 'searchMake' AND
    Model LIKE 'searchModel' AND
    Branch LIKE '$searchBranch'
    AND Year LIKE '$searchYear'

(Я разбил запрос, чтобы его было легче читать).

Теперь спросите себя: «Что произойдет, если $minPrice будет пустым»? Результирующий запрос будет выглядеть так:

SELECT Id, Make, Model, Year, Price, SpecialPrice, Branch, StockNO
FROM Vehicle
WHERE 
    Price >=  AND
    Price <= 100 AND
    Make LIKE 'something' AND
    Model LIKE 'something' AND
    Branch LIKE 'something'
    AND Year LIKE 'something'

Это недопустимый SQL: вы получите сообщение об ошибке. Подобные вещи могут и будут происходить со всеми другими значениями, которые вы вставляете таким образом.

Кроме того, я заметил из вашего сообщения об ошибке, что вы ищете такие значения, как --All Models--. Скорее всего, в инвентаре нет моделей с таким названием. Если вы хотите обрабатывать такие значения, вам нужно настроить их в коде перед отправкой в ​​базу данных.

Есть несколько способов, которыми вы можете обрабатывать запросы:

  1. вы можете написать свой код таким образом, чтобы он перестраивал список предложений WHERE на основе значений, предоставленных пользователем, или
  2. вы можете указать разумные значения по умолчанию для любых значений, которые пользователь опускает, и заменить любые значения, такие как «Все модели», чем-то, что будет соответствовать всем значениям в базе данных.

Теперь к вопросу о том, как получить результаты, которых вы ожидаете: подумайте, как вы хотите искать. В вашем случае вы получите результаты только в том случае, если будут соблюдены все условия, т.е. если пользователь введет Make="Ford" и Model="Civic" - вы ничего не получите. Это может быть то, как вы хотите, чтобы он работал, или вы можете захотеть, чтобы он возвращал список всех Ford и всех Honda Civics.

Наконец, по поводу комментария @Dagon выше - вам следует изучить использование параметров для ваших запросов. Это избавит вас от необходимости использовать такие функции, как addslashes, а также защитит вас от SQL-инъекций.

person Kryten    schedule 03.04.2014
comment
Пользователь не сможет выбрать Ford в качестве марки, а затем выбрать Civic в качестве модели, потому что я реализовал каскадное окно выбора. Таким образом, блок брендов получает информацию из базы данных, а блок моделей получает информацию из базы данных, относящуюся к информации в блоке брендов. Поэтому, если вы выберете Ford, вы сможете выбрать только Fiesta, Focus или Ranger и так далее. - person Deon; 04.04.2014
comment
Но это должно работать так: если пользователь выбирает только марку или марку и год, информация для этого должна быть напечатана. Например, Я выбираю Форд и 2012 года, все возможные форды только с 2012 года должны быть напечатаны, будь то Фиеста или Фокус или что там еще. Аналогично с другими коробками. Но вы ДОЛЖНЫ выбрать марку. - person Deon; 04.04.2014
comment
Кстати, если я уберу все, кроме поля выбора марки и года, поисковый запрос будет работать на 100%, как и ожидалось. Но, к сожалению, это не то, чего хочет мой клиент. Если только! - person Deon; 04.04.2014
comment
Все сводится к вашему синтаксису SQL — создайте несколько запросов, которые работают для множества различных комбинаций входных данных, а затем подумайте, как бы вы построили эти запросы в своем коде. - person Kryten; 04.04.2014
comment
Я создал запрос с маркой, моделью, филиалом и годом, и он отображает желаемые результаты. Кажется, что здесь проблема в структуре sql с диапазоном цен. - person Deon; 04.04.2014