40 votes

Échapper aux caractères génériques MySQL

Sur un ancien serveur, je suis sur que je ne peux pas utiliser les requêtes préparées, je suis en train d'essayer de totalement échapper à la saisie de l'utilisateur avant de l'envoyer à MySQL. Pour cela, je suis en utilisant la fonction PHP mysql_real_escape_string.

Puisque cette fonction n'échappe pas à la MySQL jokers % " et " _ " je suis l'aide d' addcslashes d'échapper à ces derniers aussi bien.

Lorsque j'envoie quelque chose comme:

test_test " ' 

à la base de données et puis le lire la base de données montre:

test\_test " ' 

En regardant cela, je ne comprends pas pourquoi l' _ a une barre oblique inverse mais le " et " ne pas. Car ils sont tous échappés avec \ sûrement _ 'et de" tous les mêmes, c'est à dire tous ont le caractère d'échappement visible ou tous les pas visible.

Sont l'échappement \s automatiquement rejetée pour

Quelqu'un peut-il expliquer cela?

95voto

bobince Points 270740

_ et % ne sont pas des caractères génériques dans MySQL en général, et ne doit pas être échappé aux fins de la mise en littéraux de chaîne. mysql_real_escape_string est correct et suffisant pour cela. addcslashes ne doit pas être utilisé.

_ et % spéciales uniquement dans le contexte de l' LIKE-matching. Lorsque vous voulez préparer des chaînes pour littérale utilisation en LIKE déclaration, de sorte qu' 100% correspond à cent pour cent et pas n'importe quelle chaîne de caractères commençant par une centaine de, vous disposez de deux niveaux d'échapper à s'inquiéter.

La première, c'est COMME s'échapper. COMME la manipulation se déroule entièrement à l'intérieur de SQL, et si vous voulez transformer une chaîne de caractères dans un littéral COMME expression, vous devez effectuer cette étape , même si vous utilisez de paramétrer des requêtes!

Dans ce schéma, _ et % sont spéciaux et doivent être échappés. Le caractère d'échappement doit également être échappé. Selon la norme ANSI SQL, de caractères autres que celles-ci ne doivent pas être échappé: \' serait une erreur. (Bien que MySQL seront généralement vous permettre de sortir avec elle.)

Ayant fait cela, vous passez au deuxième niveau de l'échappement, qui est âgé de plaine littéral de chaîne de s'échapper. Cela a lieu en dehors de SQL, création de SQL, donc doit être fait après la COMME pour échapper à l'étape. Pour MySQL, c'est - mysql_real_escape_string comme avant; pour d'autres bases de données, il y aura une fonction différente, vous pouvez simplement utiliser des requêtes paramétrées pour éviter d'avoir à le faire.

Le problème qui mène à la confusion ici, c'est que MySQL utilise une barre oblique inverse comme un caractère d'échappement pour les deux imbriqués échapper étapes! Donc si vous voulez correspondre à une chaîne à l'encontre d'un littéral signe de pourcentage, vous devez double-barre oblique-évasion et de dire LIKE 'something\\%'. Ou, si c'est en PHP " littérale qui utilise également la barre oblique inverse s'échapper, "LIKE 'something\\\\%'". Argh!

Cela est inexact, selon la norme ANSI SQL, qui dit que: dans les littéraux de chaîne barres obliques inverses dire littérale barres obliques inverses et le moyen d'échapper à une seule apostrophe ''; dans des expressions COMME il n'y a pas de caractère d'échappement par défaut.

Donc, si vous voulez à l'évasion dans un portable, il vous faut remplacer la valeur par défaut (mauvais) comportement et de spécifier votre propre caractère d'échappement, à l'aide de l' LIKE ... ESCAPE ... construire. Pour la santé mentale, nous allons choisir autre chose que de la merde barre oblique inverse!

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 ...";

ou avec des paramètres (par exemple. AOP):

$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);

(Si vous voulez plus de portabilité partie du temps, vous pouvez aussi vous amuser à essayer de compte pour MS SQL Server et Sybase, où l' [ de caractère est également à tort spécial en LIKE déclaration et a échappé. argh.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X