2011-12-23 43 views
3

好的,所以我對PHP和mysql相當陌生。我正在創建一個php前端到mysql數據庫。我使用PDO驅動程序來訪問數據庫,因爲它可以防止SQL注入攻擊。到目前爲止,一直很好,直到我遇到這個問題。我有一個搜索功能,用戶可以輸入公司名稱全部或部分來搜索關於它的數據。在PDO語句中將正則表達式綁定到PDO參數

這裏是我正在使用的數據庫進行搜索PDO聲明:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP :name 
ORDER BY CompName ASC LIMIT 1 

於是我可以準備,綁定什麼用戶在搜索領域的參數名稱和執行該語句。只要用戶沒有輸入任何元字符就行。這裏是我插入到PDO聲明而不是名稱的基本正則表達式:
^ whatusertyped - 因爲最初我在尋找一個完整的匹配項。由於一些公司名稱包含句號,所以我希望用戶能夠鍵入這些字符,並使用我的正則表達式將它們作爲文字而不是元字符。到目前爲止,這是我是如何被替換元字符來讓他們的字面含義:

用戶類型:C.尋找與C.開頭的公司名稱

PHP函數插入^和\\\\得到^ C \\的輸出。

mysql獲取:^ C \\。並在期限爲字面的公司名稱的開頭搜索C.並不是要說「尋找通配符」。

所以我想爲C.因爲在數據庫中有一家公司名稱開始像這樣,我應該得到一個匹配,但我沒有,PDO語句返回一個空數組。

我也嘗試查詢:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP "^C\\\\." 
ORDER BY CompName ASC LIMIT 1 

直接在MySQL和回來比賽,我也直接執行,而不準備,綁定在PHP的查詢和回來比賽。這個問題在我看來是在準備和綁定搜索項到一個參數,但我一直無法弄清楚它是什麼以及如何解決它。我真的想使用綁定,並像我說的那樣準備避免sql注入。

任何幫助將不勝感激。希望我能清楚地解釋這個問題。

回答

4

我相信你綁定到:name的價值應該只是^C\.而不是^C\\.。您不需要爲級別進行任何轉義,只需爲正則表達式級別(即.\.)執行轉義。

此外,請考慮使用WHERE CompName LIKE 'C.%'。這裏你不需要一個正則表達式。你可以使用像這樣:

function like_escape($s) { 
// Do like-expression escaping 
    return addcslashes($s, '%_'); 
} 
$searchprefix = 'C.'; 
$sql = 'SELECT CompName FROM CompanyName WHERE CompName LIKE ? ORDER BY CompName ASC'; 
$stmt = $db->prepare($sql); 
$likeclause = like_escape($searchprefix).'%'; 
$db->bindValue(1, $likeclause, PDO::PARAM_STR); 
$stmt->execute(); 
+1

like_escape - > [addcslashes](http://www.php.net/addcslashes)'($ VAR, '%_')' – goat

+0

啊,好極了!答覆已更改。 (雖然通常我不會相信addcslashes。) –

+0

非常感謝!現在它起作用了,我以前從未使用過LIKE,所以這非常有幫助。 – crazyferret