2009-11-23 139 views
40

我想通過php的PDO類(mysql驅動程序)進行搜索。我有以下查詢與MySQL客戶端工作(表名稱更改爲保護無辜者):PHP PDO準備語句 - MySQL LIKE查詢

SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE "%searchTerm%" 
LIMIT 25; 

不管我用搜索詞的這就像一個魅力。然而,當我轉向PHP時,我無法讓它返回任何東西。我嘗試了幾種不同的語法,看起來合乎邏輯,但我沒有嘗試過。這裏是我的現有代碼:

$handle = fopen('/foo/bar/test.log', 'w+'); 
fwrite($handle, "doSearch, with search term: $searchTerm\n"); 
$sql = 
'SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE :searchTerm 
LIMIT 25'; 

try { 
$dbh = new PDO('mysql:host=localhost;dbname=awdb', "user", "password"); 
fwrite($handle, "connected to DB\n"); 
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

while ($row = $prep->fetch(PDO::FETCH_ASSOC)) { 
    $i++; 
    $result[$i]['subText'] = $row['hs_pk']; 
    $result[$i]['subText'] = $row['hs_text']; 
    $result[$i]['subDid'] = $row['hs_did']; 
    $result[$i]['devDid'] = $row['hd_did']; 
    $result[$i]['devText'] = $row['hd_text']; 
    $result[$i]['vendorText'] = $row['hv_text']; 
    $result[$i]['classText'] = $row['hc_text']; 
} 
    $dbh = null; 
} 
catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

我試過以下,以及(SQL WHERE子句&製備型>執行行是所有變化):

WHERE hs.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 

WHERE hs.hs_text LIKE "%:searchTerm%" 
$ret = $prep->execute(array(':searchTerm' => $searchTerm)); 

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

等等

+1

這可能只是一個轉置問題,但你有沒有封閉的SQL語句 - 你需要把一個單引號(')在它的結尾。 –

+0

這是一個換位問題。如果我忘記了'我確信PHP會完全嚇壞了,哈哈。儘管感謝您的快速回復。 – TIm

+1

當你var_dump()$ dbh,$ prep和$ ret時,你會得到什麼?他們是否值你期望?您是否嘗試過使用mysql_ *系列函數運行相同的查詢以進行比較? – jkndrkn

回答

93
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

這是錯誤的。你不需要雙引號。

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

這也是錯誤的。 嘗試用:

$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

說明:預處理語句不只是做一個字符串替換。它們完全獨立於查詢傳輸數據。僅在將值嵌入到查詢中時才需要引用。

+0

謝謝你的解釋。它可能無法解決這個問題,但我會將它存儲在我的記憶中供將來使用。 – TIm

+26

@Tm你仍然應該接受他的回答。它直接回答你的問題。它不花你任何東西來接受。 –

-5

嗯,我解決了這個問題。坦率地說,我是一個白癡......謝謝大家看到這個,並給予很好的反饋。問題是表名中的拼寫錯誤(我改變了,所以沒人在這裏能看到我的問題,以......開頭)。但是,這些建議讓我發現了這個問題,所以非常感謝你,adam,jkndrkn和troelskn。

爲了記錄在案,下面結合效果很好:

WHERE aw_hcl_subdevices.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 
+14

-1這不是正確的方法。您應該*不*使用CONCAT()來處理三個* static *字符串文字,因爲它會向您顯示特定類型的SQL注入(我忘記了名稱)。 –

+4

不知道誰是這些人誰upvoted上述評論,但奇怪的是 - 他們沒有設法命名注射。可能因爲這種「注射」根本不存在。 –

+0

想從@ TheodoreR.Smith那裏聽到它,如果他仍然在附近。 [更具體地說,在這個不同的問題](http://stackoverflow.com/questions/22740375/why-should-you-not-use-concat-for-static-string-literals) – Prix

-2
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array('searchTerm' => $searchTerm)); 
+4

這個anser是不是完整的(到$ sql你是指?),是missimg一些信息(如何使「.. LIKE'%FOO%'」搜索?),並沒有任何解釋。像這樣的一些代碼不是一個答案,國際海事組織,只是一個無關緊要的事情。 – Redips77