在這個方案中,_
和%
是特殊的,必須轉義。轉義字符也必須被轉義。根據ANSI SQL,除這些以外的字符必須不能被轉義:\'
將是錯誤的。 (儘管MySQL通常會讓你擺脫困境。)
完成此操作後,您繼續進行第二級轉義,這是一種普通的舊字符串文字轉義。這發生在SQL之外,創建SQL,因此必須在LIKE轉義步驟之後完成。對於MySQL,如前所述,這是mysql_real_escape_string
;對於其他數據庫會有不同的功能,您可以使用參數化查詢來避免必須這樣做。
這裏導致混淆的問題是在MySQL中使用反斜槓作爲轉義字符來嵌套轉義步驟!所以,如果你想匹配一個字符串與字面百分號,你必須雙反斜槓轉義,並說LIKE 'something\\%'
。或者,如果這是一個PHP "
文字,它也使用反斜槓轉義,"LIKE 'something\\\\%'"
。哎呀!
根據ANSI SQL,這是不正確的,它說:在字符串文字反斜槓意思是文字反斜槓和轉義單引號的方式是''
;在LIKE表達式中默認情況下根本沒有轉義字符。
因此,如果您想以便攜方式使用LIKE轉義,則應使用LIKE ... ESCAPE ...
構造來覆蓋默認(錯誤)行爲並指定您自己的轉義字符。爲了理智,我們會選擇除了該死的反斜槓之外的東西!
function like($s, $e) {
return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}
$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";
或參數(例如,在PDO):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
(如果您想了解更多的便攜性派對的時候,你也可以有樂趣試圖解釋MS SQL Server和Sybase,其中[
字符也是錯誤的,在LIKE
聲明中是特殊的,並且必須被轉義。)
我會再次爲「該死的反斜槓!」+1。 – BoltClock 2010-09-10 10:30:35
謝謝,現在只是吸收這個...這真的幫助我擴展我的基本知識。愚蠢的是,儘管我並沒有使用任何LIKE語句,並且由於我認爲(請確認)%和_在LIKE語句中是瘋狂的,我實際上正在逃避%和_,實際上我正在浪費我的時間。但是,這讓我想到你爲什麼要在LIKE語句的上下文中轉義%或_。當然,使用LIKE語句的唯一原因是你可以使用它的通配符。 (請原諒我在這方面的有限知識) – Columbo 2010-09-10 11:06:05
當然,但希望能夠搜索文字'%'或'_'字符是非常自然的。如果用戶在前端搜索'50%',那麼他們可能意味着他們正在尋找一個包含'50%'的字符串,而不是任何含有'50'的字符串。 – bobince 2010-09-10 11:08:29