1

I have a html form tat my user can use to search through a table in my MYSQL database. By default if you just hit go it will display the entire table, however I would like them to be able select certain fields and my php form to search via the fields that are filled in.

I seem to be unable to find a way of doing this without writing a seperate query for all 11 inputs in the different combinations they could be entered in, which comes out at a total of 76 queries..

If anyone has a way to simplify this I would love any advice.

I have tried just running a query with the AND operator but that doesnt work as some variables can be left empty and that will return no result, not sure if that is what is upposed to happen, but that is what is happening.

my html and php:

http://jsbin.com/oquwid/1/edit

PHP

$sql = "SELECT * FROM  ".$tbl_name." 
WHERE fname='".$fname."' 
and lname='".$lname."' 
and city='".$city."'
and phone='".$pohne."'
and interest_inet='".$internet."'
and interest_tv='".$television."'
and interest_voice='".$voice."'
and submission_ip='".$ip."'
and inquiry_handled='".$handled."'";
$result = mysql_query($sql);

echo "<table border='1'>";
echo "<tr>";
$i = 0;

while ($i < mysql_num_fields($result))
{
    $meta = mysql_fetch_field($result, $i);   
    echo "<th>".$meta->name."</th>";
    $i++;
}

while ($row = mysql_fetch_row($result))
{
    echo '<tr>';

foreach($row as $item)
{
    echo "<td>".$item."</td>";
}

echo '</tr>';
echo $row;
}

echo "</table>";
Nick
  • 643
  • 3
  • 7
  • 19
  • Again, Welcome to Stack Overflow! [**Please, don't use `mysql_*` functions in new code**](http://bit.ly/phpmsql). They are no longer maintained [and are officially deprecated](https://wiki.php.net/rfc/mysql_deprecation). See the [**red box**](http://j.mp/Te9zIL)? Learn about [*prepared statements*](http://j.mp/T9hLWi) instead, and use [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli) - [this article](http://j.mp/QEx8IB) will help you decide which. If you choose PDO, [here is a good tutorial](http://j.mp/PoWehJ). – Madara's Ghost Jan 06 '13 at 23:04
  • @MadaraUchiha i have found i solution to this and posted it in the answers. thought you may want to see it. – Nick Jan 07 '13 at 03:02

4 Answers4

2

You could append parts to the query depending on which are filled in:

if(!empty($fname) || !empty($lname) || !empty($city) || etc.etc.) {
   $sql = "SELECT * FROM  $tbl_name WHERE ";

   $queryParts = array();
   if($fname  != "") { 
      $queryParts[] = " fname='$fname'";
   }
   if($lname != "") {
      $queryParts[] = " lname='$lname'";
   }
   etc.etc.

   $sql .= implode(" AND ", $queryParts);

   // do query, etc.
}
else {
   // Don't do query if no parameters are specified
}

You also need to make sure that you escape all of your query parameters before you use them or risk having someone ravage your data.

The following uses loops to avoid duplicate code:

$fieldIsSpecified = false;
$queryFields = array('fname' => $fname, 'lname' => $lname, 'city' => $city, etc...);
foreach($queryFields as $column => $value) {
    if(!empty($value){
         $fieldIsSpecified = true;
         break;
    }
}
if($fieldIsSpecified) {
   $sql = "SELECT * FROM  $tbl_name WHERE ";

   $queryParts = array();
   foreach($queryFields as $column => $value) {
      if(!empty($value)) {
          $queryParts[] = " $column = '$value'";
      }
   }

   $sql .= implode(" AND ", $queryParts);

   // do query, etc.
}
else {
   // Don't do query if no parameters are specified
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • Please consider that it could be that the variable you're refering to is not initialized, in which case an E_NOTICE is thrown. See the accepted answer [here](http://stackoverflow.com/questions/11510328/e-notice-how-useful-is-it-really-to-fix-every-one) . Or at least the 2nd and 3th paragraph if you tld id. – Daneo Jan 06 '13 at 22:31
  • Because there is no sign of a start nor end-tag nor an indication of where those values get filled. – Daneo Jan 06 '13 at 22:43
1

The reason you're query isn't working if a value is not filled in, is probably because the query results in this (given first name is empty)

SELECT * FROM $tbl_name WHERE fname=''

And there probably isn't a user having no first name.

Further, you considered adding a flag per requested info, and on base of that either add or remove the needed part to the select part of the query ?

For example,

$sql = "SELECT * FROM $tbl_name WHERE "; 
$queryChanged = false;
if (isset($fname)){
    if (!empty($fname)){
        $sql .= "fname='$fname' ";
        $queryChanged=true;
    }
}
if (isset($lname)){
    if (!empty($lname)){
        $sql .= ($queryChanged) ?  " AND lname='$lname'" : "lname='$lname'";
        $queryChanged = true;
    }
}
... //Continue the logic

I'd recommend you to read this post about select * as well as this about user input and how to handle it

Community
  • 1
  • 1
Daneo
  • 508
  • 3
  • 17
  • @john-doe Added why it is that the query stops working if one value is missing. – Daneo Jan 06 '13 at 22:49
  • Saw that and thanks, i hope to get this working by tomorrow morning, and i will post my final code when its all said and done. – Nick Jan 07 '13 at 01:07
  • I added the solution that i ended up using – Nick Jan 07 '13 at 03:01
  • I hate to be that guy, but i am simply having a hard time wrapping my mind arounf this, anyway you can explain it to me differently? is the $queryChanged supposed to symbolize the pulling from the database? – Nick Jan 07 '13 at 15:30
  • $queryChanged is a variable that's keeping track of whether anything has been added to the WHERE clause so far, to determine whether to append " AND " or not. I also recommend trying out the second of the two approaches I described below, as it's quite a bit more concise and easy to modify. – JLRishe Jan 08 '13 at 05:08
0

this is how i am going to have to do it

php:`

//if just lname is set
if(empty($start_date) && empty($end_date) && empty($fname) && isset($lname) && empty($city) &&
 empty($internet) && empty($television) && empty($voice) && empty($phone) && empty($ip) && 
 empty($handled) && empty($not_handled)){ 
$sql = "SELECT * FROM  ".$tbl_name."
WHERE lname='".$lname."'";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
$meta = mysql_fetch_field($result, $i);   
echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
echo '<tr>';
foreach($row as $item)
{
    echo "<td>".$item."</td>";
}   
echo '</tr>';
}
echo "</table>";
exit();
}


//if just city is selected
if(empty($start_date) && empty($end_date) && empty($fname) && empty($lname) && isset($city) &&
 empty($internet) && empty($television) && empty($voice) && empty($phone) && empty($ip) && 
 empty($handled) && empty($not_handled)){ 
$sql = "SELECT * FROM  ".$tbl_name."
WHERE city='".$city."'";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
    $meta = mysql_fetch_field($result, $i);   
    echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
    echo '<tr>';
foreach($row as $item)
{
    echo "<td>".$item."</td>";
}   
echo '</tr>';
}
echo "</table>";
exit();
}

And etc... i am going to have to repeat this process until i cover all, 76 i believe, possibilites. thnkfully its just a lot of copy paste. thanks for the help everyone

Nick
  • 643
  • 3
  • 7
  • 19
  • You can handle each empty($var) as a different if, and if it is empty, add it to the query as in my example. Basically building the string dynamically. There is no need to copy paste it that many times. Please review my answer, the purpose behind each seperate if is, if e.g. lastname is set, add "firstname='$fname'" to the string. A lot less verbose. Try it, the only thing you have to take into account is that if it is not the first in line (the bool in my answer) then you have to add " AND " + the rest of the query. – Daneo Jan 07 '13 at 08:16
  • Or take a look at the loop JLRise uses, it uses the index of the array as column value (fname=), and the actual $value in the array ("John Doe") resulting in "fname='John Doe'". The implode transforms it into a String, and puts the " AND " String between each element. Take a look at it, it will result in more maintainable code! – Daneo Jan 07 '13 at 08:20
-1

First don't use MYSQL_*. Use PDO

Second, with your code, your are requiring all fields to be filled.

If you don't wanna do that then go this way:

You can use WHERE 1=1 , but it's not recommended !!!!!

 $sql = "SELECT * FROM  ".$tbl_name." WHERE confirm = '0' ";

 $sql .= "AND fname = ".$fname."";
 $sql .= "AND lname = ".$lname."";
 $sql .= "AND city = ".$city."";
 $sql .= "AND phone = ".$pohne."";
 $sql .= "ORDER BY date DESC";
 $result = mysql_query($sql);

 echo "<table border='1'>";
 echo "<tr>";
 $i = 0;

 while ($i < mysql_num_fields($result))
 {
 $meta = mysql_fetch_field($result, $i);   
 echo "<th>".$meta->name."</th>";
 $i++;
 }

 while ($row = mysql_fetch_row($result))
  {
  echo '<tr>';

  foreach($row as $item)
  {
  echo "<td>".$item."</td>";
   }

   echo '</tr>';
   echo $row;
     }

   echo "</table>";
Rocks
  • 511
  • 1
  • 6
  • 19
  • I don't get your question? – Rocks Jan 06 '13 at 22:38
  • Is $fname a name of an input? – Rocks Jan 06 '13 at 23:05
  • 1
    This post doesn't solve the problem John Doe described (all the query fields are still reqiured; you've just removed some of them) and has the added issue that there won't be quotes around the query values in the SQL: ... AND fname = Bob AND lname = Smith AND city = Springfield, etc. – JLRishe Jan 06 '13 at 23:06
  • His problem is that he only wants to query based on the values that the user has filled in. – JLRishe Jan 06 '13 at 23:20