_
e %
non sono caratteri jolly in MySQL in generale e non devono essere sottoposti a escape allo scopo di inserirli in normali stringhe letterali. mysql_real_escape_string
è corretto e sufficiente per questo scopo. addcslashes
non deve essere utilizzato.
_
e %
sono speciali esclusivamente nel contesto di LIKE
-corrispondenza. Quando vuoi preparare le stringhe per l'uso letterale in un LIKE
dichiarazione, in modo che 100%
corrisponde al cento per cento e non a qualsiasi stringa che inizia con cento, hai due livelli di evasione di cui preoccuparti.
Il primo è COME scappare. La gestione di LIKE avviene interamente all'interno di SQL e se si desidera trasformare una stringa letterale in un'espressione LIKE letterale è necessario eseguire questo passaggio anche se si utilizzano query parametrizzate !
In questo schema, _
e %
sono speciali e devono essere evasi. Anche il carattere di escape deve essere sottoposto a escape. Secondo ANSI SQL, caratteri diversi da questi non devono essere sottoposto a escape:\'
sarebbe sbagliato. (Anche se MySQL in genere ti consente di farla franca.)
Fatto ciò, si passa al secondo livello di escape, che è un semplice escape letterale di una vecchia stringa. Ciò avviene al di fuori di SQL, creando SQL, quindi deve essere eseguito dopo il passaggio LIKE di escape. Per MySQL, questo è mysql_real_escape_string
come prima; per altri database ci sarà una funzione diversa, di cui puoi semplicemente usare query parametrizzate per evitare di doverlo fare.
Il problema che crea confusione qui è che in MySQL usa una barra rovesciata come carattere di escape per entrambi i passaggi di escape annidati! Quindi, se si desidera confrontare una stringa con un segno di percentuale letterale, è necessario eseguire il double-backslash-escape e dire LIKE 'something\\%'
. Oppure, se è in un "
PHP letterale che usa anche l'escape della barra rovesciata, "LIKE 'something\\\\%'"
. Argh!
Questo non è corretto secondo ANSI SQL, che dice che:nei valori letterali di stringa le barre inverse significano le barre inverse letterali e il modo per sfuggire a una virgoletta singola è ''
; nelle espressioni LIKE non è presente alcun carattere di escape per impostazione predefinita.
Quindi, se vuoi fare LIKE-escape in modo portatile, dovresti ignorare il comportamento predefinito (sbagliato) e specificare il tuo carattere di escape, usando LIKE ... ESCAPE ...
costruire. Per sanità mentale, sceglieremo qualcosa di diverso dalla dannata barra rovesciata!
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 ...";
o con parametri (es. in PDO):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
(Se vuoi più tempo di festa della portabilità, puoi anche divertirti provando a tenere conto di MS SQL Server e Sybase, dove il [
il carattere è anche, erroneamente, speciale in un LIKE
dichiarazione e deve essere evitato. arg.)