too long

I'm trying to create an Advanced Searching form that sort of look like this ;

http://img805.imageshack.us/img805/7162/30989114.jpg

but what should I write for the query?

I know how to do it if there is only two text box but three, there's too many probability that user will do.

$query = "SELECT * FROM server WHERE ???";

What should I write for the "???"

I know how to use AND OR in the query but lets say if the user only fill two of the textbox and one empty. If I write something like this ;

$query = "SELECT * FROM server WHERE model='".$model."' and brand='".$brand."' and   SN='".$SN.'" ";

The result will return as empty set. I want the user can choose whether to fill one,two or three of the criteria. If I use OR, the result will not be accurate because if Model have two data with the same name (For example :M4000) but different brand (For example : IBM and SUN). If I use OR and the user wants to search M4000 and SUN, it will display both of the M4000. That's why it is not accurate.

If the user can decide how many criteria he wants to enter for your search and you want to combine those criteria (only those actually filled by the user), then you must dynamically create your SQL query to include only those fields in the search that are filled by the user. I'll give you an example.

The code for a simple search form could look like this:

$search_fields = Array(
    // field name => label
   'model'     => 'Model',
   'serialNum' => 'Serial Number',
   'brand'     => 'Brand Name'
);
echo "<form method=\"POST\">";
foreach ($search_fields as $field => $label) {
    echo "$label: <input name=\"search[$field]\"><br>";
}
echo "<input type=\"submit\">";
echo "</form>";

And the code for an actual search like this:

if (isset($_POST['search']) && is_array($_POST['search'])) {
    // escape against SQL injection
    $search = array_filter($_POST['search'], 'mysql_real_escape_string');
    // build SQL
    $search_parts = array();
    foreach ($search as $field => $value) {
        if ($value) {
            $search_parts[] = "$field LIKE '%$value%'";
        }
    }
    $sql = "SELECT * FROM table WHERE " . implode(' AND ', $search_parts);
    // do query here
}
else {
    echo "please enter some search criteria!";
}

In the above code we dynamically build the SQL string to do a search ("AND") for only the criteria entered.

You have to provide $model, $brand, $serial which come from your search-form.

$query = "SELECT * FROM `TABLE` WHERE `model` LIKE '%$model%' AND `brand` LIKE '%$brand%' AND `serial` LIKE '%$serial%'";

Also take a look at the mysql doc

http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html

For those framiliar with mysql, it offers the ability to search by regular expressions (posix style). I needed an advanced way of searching in php, and my backend was mysql, so this was the logical choice. Problem is, how do I build a whole mysql query based on the input? Here's the type of queries I wanted to be able to process:

  1. exact word matches
  2. sub-string matches (I was doing this with like "%WORD%")
  3. exclude via sub-string match
  4. exclude via exact word match

A simple regexp query looks like:

select * from TABLE where ROW regexp '[[:<:]]bla[[:>:]]' and ROW regexp 'foo';

This will look for an exact match of the string "bla", meaning not as a sub-string, and then match the sub-string "foo" somewhere.

So first off, items 1 and 4 are exact word matches and I want to be able to do this by surrounding the word with quotes. Let's set our necessary variables and then do a match on quotes:

$newq = $query; # $query is the raw query string
$qlevel = 0;
$curquery = "select * from TABLE where "; # the beginning of the query
$doneg = 0;
preg_match_all("/\"([^\"]*)\"/i", $query, $m);
$c = count($m[0]);
for ($i = 0; $i < $c; $i++) {
$temp = $m[1][$i]; # $temp is whats inside the quotes

Then I want to be able to exclude words, and the user should be able to do this by starting the word with a dash (-), and for exact word matches this has to be inside the quotes. The second match is to get rid of the - in front of the query.

 if (ereg("^-", $temp)) {
          $pc = preg_match("/-([^-]*)/i", $m[1][$i], $dm);
          if ($pc) {
               $temp = $dm[1];
               }
          $doneg++;
          }

Now we will set $temp to the posix compliant exact match, then build this part of the mysql query.

 $temp = "[[:<:]]".$temp."[[:>:]]";
 if ($qlevel) $curquery .= "and "; # are we nested?
 $curquery .= "ROW "; # the mysql row we are searching in
 if ($doneg) $curquery .= "not "; # if dash in front, do not
 $curquery .= "regexp ".quote_smart($temp)." ";
     $qlevel++;
 $doneg = 0;
 $newq = ereg_replace($m[0][$i], "", $newq);
 }

The variable $newq has the rest of the search string, minus everything in quotes, so whatever remains are sub-string search items falling under 2 and 3. Now we can go through what is left and basically do the same thing as above.

    $s = preg_split("/\s+/", $newq, -1, PREG_SPLIT_NO_EMPTY); #whitespaces
    for ($i = 0; $i < count($s); $i++) {
         if (ereg("^-", $s[$i])) { # exclude
              sscanf($s[$i], "-%s", $temp); # this is poor
              $s[$i] = $temp;
              $doneg++;
              }
         if ($qlevel) $curquery .= "and ";
         $curquery .= "ROW "; # the mysql row we are searching in
         if ($doneg) $curquery .= "not ";
         $curquery .= "regexp ".quote_smart($s[$i])." ";
         $qlevel++;
     $doneg = 0;
     }
# use $curquery here in database

The variable $curquery now contains our built mysql query. You will notice the use of quote_smart in here, this is a mysql best practice from php.net. It's the only mention of security anywhere in this code. You will need to run your own checking against the input to make sure there are no bad characters, mine only allows alpha-numerics and a few others. DO NOT use this code as is without first fixing that.

A basic search would work like this:

"SELECT * FROM server WHERE column_name1 LIKE '%keyword1%' AND column_name2 LIKE '%keyword2%' .....";

This would be case for matching all parameters.For matching any one of the criteria, change ANDs to ORs

Try this code

<?php

$model="";
$brand="";
$serialNum="";

$model=mysql_real_escape_string($_POST['model']);
$brand=mysql_real_escape_string($_POST['brand']);
$serialNum=mysql_real_escape_string($_POST['serialNum']);

$query=" select * from server";
$where_str=" where ";

if($model == "" && $brand == "" && $serialNum == "")
{
  rtrim($where_str, " whrere "); 
}
else
{
   if($model != "")
   {
     $where_str.= "  model like '%$model%' AND ";
   }
   if($brand != "")
   {
     $where_str.= "  brand like '%$brand%' AND ";
   }
   if($serialNum != "")
   {
     $where_str.= "  serialNum like '%$serialNum%' AND ";
   }

rtrim($where_str, " AND ");
}

$query.= $where_str;
$records=mysql_query($query);
?>