_
и %
не са заместващи знаци в MySQL като цяло и не трябва да се избягват за целите на поставянето им в нормални низови литерали. mysql_real_escape_string
е правилно и достатъчно за тази цел. addcslashes
не трябва да се използва.
_
и %
са специални единствено в контекста на LIKE
-съчетаване. Когато искате да подготвите низове за буквално използване в LIKE
изявление, така че 100%
съвпада на сто процента, а не на всеки низ, започващ със сто, имате две нива на бягство, за които да се притеснявате.
Първата е КАТО бягство. LIKE обработката се извършва изцяло в SQL и ако искате да превърнете литерален низ в литерален израз LIKE, трябва да изпълните тази стъпка дори ако използвате параметризирани заявки !
В тази схема _
и %
са специални и трябва да бъдат избягани. Ескейпиращият символ също трябва да бъде екраниран. Според ANSI SQL символи, различни от тези не трябва да се екранира:\'
би било погрешно. (Въпреки че MySQL обикновено ви позволява да се разминете.)
След като направите това, вие преминавате към второто ниво на екраниране, което е обикновен стар стринг literal escaping. Това се извършва извън SQL, създавайки SQL, така че трябва да се направи след стъпката за избягване на LIKE. За MySQL това е mysql_real_escape_string
по старому; за други бази данни ще има различна функция, като от вас можете просто да използвате параметризирани заявки, за да не се налага да го правите.
Проблемът, който води до объркване тук, е, че в MySQL използва обратна наклонена черта като escape символ и за двете вложени стъпки за избягване! Така че, ако искате да съпоставите низ с буквален знак за процент, ще трябва да изплъзнете двойна обратна наклонена черта и да кажете LIKE 'something\\%'
. Или, ако това е в PHP "
литерал, който също използва избягване на обратна наклонена черта, "LIKE 'something\\\\%'"
. Ага!
Това е неправилно според ANSI SQL, който казва, че:в низовите литерали обратните наклонени черти означават буквални обратни наклонени черти и начинът за избягване на единична кавичка е ''
; в изразите LIKE по подразбиране няма никакъв escape символ.
Така че, ако искате да LIKE-escape по преносим начин, трябва да замените поведението по подразбиране (грешно) и да посочите свой собствен escape символ, като използвате 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
изявление и трябва да се избяга. ара.)