-1

I have my search form, where the cities are fetched from the database, but how can I make the search work when I select some option? I need to get "printed" everything about all houses that are in that particular selected city

HTML Form:

<form action="./server/Search.php" method="post">

<div class="col-auto mt-5">
  
<select name="city" class="form-select" aria-label="Default select example ">
  <option selected disabled>City</option>
  <?php  
    $query = $conn->query("SELECT * FROM `houses`") or die(mysqli_error());
    while($fetch = $query->fetch_array()){
    ?>
  <option value=""><?php echo $fetch['city']?></option>
  <?php
    }
    ?>
</select>
</div>

  <div class="col-auto mt-5">
    <button type="search" name="search" class="btn btn-primary"><i class='bx bx-search-alt-2'></i></button>
  </div>
</form>

Search.php

<?php
    $con= new mysqli("localhost","root","","KBHestate");
    $name = $_post['search'];

    if (mysqli_connect_errno())
      {
      echo "Failed to connect to MySQL: " . mysqli_connect_error();
      }

$result = mysqli_query($con, "SELECT * FROM houses
    WHERE city LIKE '%{$city}%'");

while ($row = mysqli_fetch_array($result))
{
        echo $row['city'];
        echo "<br>";
}
    mysqli_close($con);
    ?>

I don't know how to connect selected option with the query. Is there any way how to handle this the best way possible?

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • You have an error. [`mysqli_error()`](https://www.php.net/manual/en/mysqli.error.php) needs one argument. Please consider switching error mode on instead. [How to get the error message in MySQLi?](https://stackoverflow.com/a/22662582/1839439) – Dharman Jan 17 '21 at 18:41

2 Answers2

1

First change in the html form, to avoid selecting columns and rows you don't need:

<?php
  $query = $link->query("SELECT distinct city FROM `houses`");
  while($fetch = $query->fetch_array(MYSQLI_ASSOC)){
    echo "<option value='{$fetch['city']}'>{$fetch['city']}</option>\n";
  }
?>

Then search.php with bind variables.

<?php
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link = new mysqli("localhost","root","","KBHestate");
    
    $name = $_POST['city'];
    $query = $link->prepare("SELECT id FROM houses where city = ?");
    $query->bind_param("s", $name);
    $query->execute();
    $query->bind_result($id);
    while($query->fetch()){
        echo "{$id}</br>\n";
    }

?>
Dharman
  • 30,962
  • 25
  • 85
  • 135
Gerard H. Pille
  • 2,528
  • 1
  • 13
  • 17
  • As the OP uses the real city name please tell me if i am right: my2 cents: If the city is "S' Hertogenbusch" - (Yes i experienced this in real life in my database) the HTML output will be garbage. -- At least it should be escaped. -- Also the use of die() seems not be recommended anymore. https://thisinterestsme.com/dont-use-die-statement/ – Alexander Dobernig Jan 04 '21 at 12:06
  • I am curious: As he wants to wants to display "everything about all houses that are in that particular selected city" will the bind_result() funtion be the best method? so he will bin every single field? – Alexander Dobernig Jan 04 '21 at 12:28
  • @AlexanderDobernig yes, bind_result($col1,$col2,...). There is an alternative, using the get_result followed by a while fetch_array from that result. A numeric fetch_array would allow you not to use individual variables, but you certainly wouldn't win in readability. – Gerard H. Pille Jan 04 '21 at 12:56
  • @AlexanderDobernig correct that the city names should be escaped, after which the search might need to unescape them again. I won't correct my answer, as you pointed out in yours, using the name is not done. – Gerard H. Pille Jan 04 '21 at 12:59
  • I would use the associative fetch_array as https://www.php.net/manual/de/mysqli-result.fetch-array.php delivers both on default and the readbility would be equal to the non prepared results. – Alexander Dobernig Jan 04 '21 at 14:21
0

It seems that a few things are missing here:

The value is missing in the HTML Form so nothing gets posted

You should not use the cities name (because there are a lot of cities with problematic characters) but a numerical id for the value.

This also means that you need a seperate lookup table with cities and the city id and join this with the houses table.

">

Then your second script search.php does not use the posted value

 $city_id = $_POST['city_id'];

[...]
now you can use $city_id in the query:

$result = mysqli_query($con, "SELECT * FROM houses
    WHERE city_id ='{$city_id}'");

BUT in fact this is not the proper way to do it - use prepared statments instead.

  • What is the meaning of the "{}" used in the select? Never use posted input directly in SQL! Learn about SQL injection and prepared statements + bind variables. – Gerard H. Pille Jan 02 '21 at 02:08
  • @GerardH.Pille It only repeated the original syntax of the original poster to help him understand his problem. Introducing new concepts into the answer would have made it probably too complicated to understand the problem and its solution for someone who does not already understand the basic concepts of a html form. This is just my opionion. Feel free to answer with a complete new code including prepared statements. – Alexander Dobernig Jan 02 '21 at 10:18
  • I wonder how an invalid statement will help the OP. – Gerard H. Pille Jan 02 '21 at 20:07
  • @GerardH.Pille What exactly is invalid in the statement? – Alexander Dobernig Jan 03 '21 at 08:58
  • The accolades, curly braces? I believe they're used by frameworks, but SQL doesn't know them. So you would be looking for "city_id = '{500}', and MySQL might not be happy with that. But again: never use input directly, always use a bind variable. – Gerard H. Pille Jan 03 '21 at 09:32
  • @GerardH.Pille No. Curly braces can be used to insert variables in strings. see: https://stackoverflow.com/questions/2596837/curly-braces-in-string-in-php PHP will replace it so it will result in the following sql query sent to the server. (Yes i have tried it with php 7.4 after your comment ;-) SELECT * FROM houses WHERE city_id ='45' Regarding your comment on prepared staments you are right. – Alexander Dobernig Jan 03 '21 at 10:14
  • Thanks for teaching me the errors of my ways. Proves one is never too old to learn. – Gerard H. Pille Jan 03 '21 at 12:32
  • @GerardH.Pille Nevermind, i only know this since last week from one of those posts and was quite embarrased that i did not know it before. ;-). But it makes life easier as there is a lot less of ." ". . – Alexander Dobernig Jan 03 '21 at 16:29