简体   繁体   中英

Multiple Search Criteria in PHP and MySql

I'm working on a motor dealership website. This dealership uses a third-party desktop application to manage the stock and the vehicles on sale. This third-party application saves the vehicle data to an Access Database (.mdb). I successfully connect to this database, as well as view individual records and so forth. All is great up to this point.

The final piece of the puzzle is an advanced search criteria. This search criteria has six inputs; brand, model (the brand and model inputs are text and they are also cascading dropdowns using AJAX), branch, year (text), min price and max price (the two price inputs are of number data type in the database).

Users will very likely not use all of the available inputs because more often than not, that would give them no results.

Also, if the search works after all that, and someone searches something but that something is not available in the database, a message has to appear informing the user that the requested vehicle is currently not available. How would I go about doing something like that?

Here's my code so far.

<?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!");
      }

  ?>

How would I make the message appear?

EDIT: The query works now and it displays the derisred results based on selections made, but all the selections have to be made otherwise it doesn't display anything.

Please keep in mind that the brand MUST be selected. It can't be all brands. Otherwise you can just view the whole table.

How can I structure the above query to have an "all models" and "any branch" and "any year" and "any price" as valid selections?

You need to think through all the possible combination of inputs and how that's going to affect the query that gets sent to the database. For example, your query is constructed via:

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'

(I've broken up the query to make it a little easier to read).

Now ask yourself: "what happens if $minPrice is empty"? The resulting query is going to look like this:

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'

That's not valid SQL: you're gonna get an error. Similar things can & will happen with all the other values you're inserting in this way.

Also, I notice from your error message that you're searching for values like --All Models-- . Chances are, there are no models in the inventory with that name. If you want to handle values like that, you'll need to adjust them in the code before submitting them to the database.

There are a couple of ways you could handle building your queries:

  1. you can write your code in such a way that it rebuilds the list of WHERE clauses based on the values provided by the user, or
  2. you can provide sensible defaults for any values that the user omits and replace any values like "All Models" with something that will match all values in the database.

Now, on the question of how to get the results you expect: think about how you want to search. The way you've got it, you will only get results if all the conditions match - ie. if the user enters Make="Ford" and Model="Civic" - you're gonna get nothing. This might be the way you want it to work, or you might want it to return a list of all the Fords and all the Honda Civics.

Finally, on the subject of @Dagon's comment above - you should look into using parameters for your queries. That will remove the need to use functions like addslashes and will also protect you from SQL injection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM