2012-03-28 112 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); 
?>