2012-03-28 175 views
2

我试图创建一个高级搜索的形式,看起来像这样;高级搜索,PHP和MySQL

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

,但我应该怎么写的查询?

我知道如何做到这一点,如果只有两个文本框,但三个,用户会做的概率太多。

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

我该写什么“???”

我知道如何在查询中使用AND OR,但让我们说如果用户只填充两个文本框和一个空的。如果我写这样的东西;

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

结果将返回为空集。我希望用户可以选择是否填写一个,两个或三个标准。如果使用OR,结果将不准确,因为如果Model有两个具有相同名称(例如:M4000)但不同品牌(例如:IBM和SUN)的数据。如果我使用OR,并且用户想要搜索M4000和SUN,它将显示两个M4000。这就是为什么它不准确。

+2

那么这取决于你的要求。用户是否必须搜索所有标准?还是只有一个标准?它也取决于你的模式。也许用你的模式更新你的问题一些样本数据,一些样本结果和你想要多标准工作的描述;以及您尝试过的方法以及您遇到的问题/错误。 – liquorvicar 2012-03-28 06:04:25

+0

用户可以选择是搜索一个,两个还是全部标准。 – 2012-03-28 06:09:10

回答

4

如果用户能决定多少的标准,他想要输入用于搜索,并且想要将这些条件(仅限用户实际填写的条件)组合在一起,那么您必须动态创建SQL查询以仅包含搜索中由用户填充的那些字段。我会给你一个例子。

一个简单的搜索页面的代码看起来是这样的:

$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>"; 

而对于这样一个实际的搜索代码:

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

在上面的代码中,我们动态生成SQL字符串只为输入的标准进行搜索(“AND”)。

+0

修复了一些错别字 – Kaii 2012-03-28 07:03:20

+0

谢谢!!有效! – 2012-03-28 07:29:08

0

您必须提供来自您的搜索表单的$ model,$ brand,$ serial。

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

而且看看mysql的文档

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

+0

但是如果用户只用两个方框搜索呢?该查询将作为空集返回,因为其中一个字段为空。 – 2012-03-28 06:15:13

+0

@ Hafiz Abdullah:在查询中简单地使用OR而不是AND。 – peipst9lker 2012-03-28 06:38:19

+0

结果将不准确。 – 2012-03-28 06:45:13

1

对于MySQL的那些framiliar,它提供了通过正则表达式(POSIX风格)搜索的能力。我需要一种先进的搜索方式,而我的后端是mysql,所以这是合乎逻辑的选择。问题是,我如何基于输入构建整个mysql查询?这是我希望能够处理查询的类型:

  1. 确切的词
  2. 子字符串匹配匹配(我用像“%WORD%”这样做)
  3. 通过子串排除比赛
  4. 通过确切的词匹配

一个简单的正则表达式查询看起来像排除:

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

这将查找字符串“喇嘛”的精确匹配,这意味着不是作为一个子字符串,然后匹配子字符串“foo”的地方。

因此,首先,第1项和第4项是精确的单词匹配,我希望能够通过用引号括住单词来做到这一点。让我们来设置我们需要的变量,然后做报价匹配:

$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 

然后,我希望能够排除的话,用户应该能够用破折号开始这个词来做到这一点( - ),而对于确切的单词匹配,这必须在引号内。第二场比赛是摆脱 - 在查询前面。

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

现在我们将$ temp设置为符合posix的精确匹配,然后构建mysql查询的这一部分。

$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); 
} 

变量$ newq具有搜索字符串的引号休息,减去一切,所以剩下什么剩下的无论是在2和3下降现在我们可以顺利通过子字符串搜索项目,基本上都与上面相同。

$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 

变量$ curquery现在包含我们构建的mysql查询。你会注意到在这里使用quote_smart,这是一个来自php.net的mysql最佳实践。这是此代码中唯一提到的安全性。您需要对输入进行自己的检查以确保没有错误的字符,我只允许使用字母数字和其他字符。如果没有先解决这个问题,请不要使用此代码。

0

一个基本的搜索将像这样工作:

“SELECT * FROM服务器里column_name1 LIKE '%关键字1%' AND column_name2 LIKE '%关键字2%' ......”;

这将是案件全部一致parameters.For匹配的标准中的任何一个,改变与门来的OR

1

试试这个代码

<?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); 
?>