2 回答

TA貢獻1815條經(jīng)驗 獲得超10個贊
_而%不是通配符在MySQL一般,而且不應(yīng)該被轉(zhuǎn)義,將它們放入普通的字符串字面量的目的。mysql_real_escape_string是正確的,足以滿足此目的。addcslashes不應(yīng)該使用。
_并且%僅在LIKE-matching 上下文中是特殊的。當您想為LIKE語句中的文字使用準備字符串時,要100%匹配百分之一百,而不僅僅是以100開頭的任何字符串,都需要擔(dān)心兩種轉(zhuǎn)義。
首先是喜歡轉(zhuǎn)義。LIKE處理完全在SQL內(nèi)部進行,如果要將文字字符串轉(zhuǎn)換為文字LIKE表達式,即使使用參數(shù)化查詢,也必須執(zhí)行此步驟!
在此方案中,_并且%是特殊的,必須進行轉(zhuǎn)義。轉(zhuǎn)義字符也必須轉(zhuǎn)義。根據(jù)ANSI SQL,除這些字符外,不得轉(zhuǎn)義:\'這是錯誤的。(盡管MySQL通常會讓您擺脫它。)
完成此操作后,您進入第二個轉(zhuǎn)義級別,這是普通的舊字符串文字轉(zhuǎn)義。這發(fā)生在SQL之外,創(chuàng)建SQL,因此必須在LIKE轉(zhuǎn)義步驟之后完成。對于MySQL,這mysql_real_escape_string和以前一樣。對于其他數(shù)據(jù)庫,它將具有不同的功能,您可以只使用參數(shù)化查詢來避免這樣做。
這里引起混亂的問題是,在MySQL中,兩個嵌套轉(zhuǎn)義步驟都使用反斜杠作為轉(zhuǎn)義字符!因此,如果要將字符串與文字百分號匹配,則必須雙反斜杠轉(zhuǎn)義并說出LIKE 'something\\%'。或者,如果在PHP "文字中也使用反斜杠轉(zhuǎn)義,則"LIKE 'something\\\\%'"。??!
根據(jù)ANSI SQL,這是不正確的,它表示:在字符串文字中,反斜杠表示文字反斜杠,而轉(zhuǎn)義單引號的方式為'';在LIKE表達式中,默認情況下根本沒有轉(zhuǎn)義符。
因此,如果要以可移植的方式進行LIKE逸出,則應(yīng)覆蓋默認(錯誤)行為,并使用該LIKE ... ESCAPE ...構(gòu)造指定自己的逸出字符。為了理智,我們將選擇除該死的反斜杠以外的其他東西!
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 ...";
或帶有參數(shù)(例如在PDO中):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
(如果您希望有更多的可移植性聚會時間,那么嘗試考慮MS SQL Server和Sybase也可能會很有趣,因為在[錯誤的情況下,該字符在LIKE語句中也很特殊,必須轉(zhuǎn)義。argh。)

TA貢獻1804條經(jīng)驗 獲得超7個贊
現(xiàn)在就開始吸收...這確實有助于我擴展基礎(chǔ)知識。愚蠢的是,盡管我實際上并未使用任何LIKE語句,但我仍在轉(zhuǎn)義%和_,并且由于我認為(請確認)%和_僅在LIKE語句的上下文中是百搭的,所以我實際上是在浪費時間。但是,那讓我想起為什么在LIKE語句的上下文中,為什么要轉(zhuǎn)義%或_。當然,使用LIKE語句的唯一原因是可以使用它的通配符。(請原諒我對此的有限知識)
添加回答
舉報