8795 sujets

Développement web côté serveur, CMS

Bonjour à vous,

Je me pose une question concernant cette fonction.

Je l'utilise dès que je fais un INSERT ou un UPDATE de données dans ma DB. Ainsi, j'évite toute injection ! et comme vous le savez également, mes apostrophes sont échappées c'est-à-dire que ceci L'espace devient ceci dans ma DB L\'espace.

Du coup, si j'affiche ce champ dans une page Web, il affiche assez logiquement ceci : L\'espace. Et avec la même idée, ce champ peut vite devenir ceci : L\\\\\\\\\\\\\\'espace car les backslashs sont eux aussi échappés !

Que faire pour éviter ceci ?

Il existe la fonction stripslashes() mais admettons que j'ai déjà dans ma DB un champ qui a comme valeur L\\\'espace, la fonction stripslashes() ne m'est déjà plus utile !

J'attend vos conseils, merci d'avance !
Modifié par Alphonse (25 Feb 2008 - 14:58)
Bonjour,

il n'y a pas de solution miracle, l'échappement fonctionne comme une échelle. Pour qu'un script marche correctement il faut qu'il monte autant d'échelons qu'il en descend, dans le cas contraire on gagnera/perdra à chaque passage un(des) niveau(x) ce qui donne vite des choses du genre L\\\\\\\\\\\\\\'espace.

Voici deux exemples, faux, ainsi qu'un juste (soulignant au passage un piège de la configuration de php):
// variable de départ
$var = addslashes("L'espace");

// l'insérer dans la base (note: les fonctions query et query_var sont fictives)
$query = sprintf('INSERT INTO `table` SET var="%s", id="1"', mysql_real_escape_string($var));
query($query);

// la récupérer et l'afficher
$query = 'SELECT var FROM `table` WHERE id="1"';
$var = query_var($query);
echo $var;

Bilan des niveaux d'échappement:
Départ: 1.
Mysql_real_escape_string (+1), 2.
Interprétation par MySQL (-1), 1.
Conclusion: le résultat gagne un niveau d'échappement à chaque passage via le script.

// récupérer la variable
$var = $_POST['ma_variable'];

// l'insérer dans la base
$query = sprintf('INSERT INTO `table` SET var="%s", id="1"', mysql_real_escape_string($var));
query($query);

// la récupérer et l'afficher
$query = 'SELECT var FROM `table` WHERE id="1"';
$var = stripslashes(query_var($query));
echo $var;

Bilan des niveaux d'échappement:
Départ: 0 ou 1 (Magic Quotes).
Mysql_real_escape_string (+1), 1 ou 2.
Interprétation par MySQL (-1), 0 ou 1.
stripslashes (-1), -1 ou 0.
Conclusion: le résultat est incertain et dépends de la configuration de php.

// récupérer la variable
$var = $_POST['ma_variable'];
if(get_magic_quotes_gpc()) {
  $var = stripslashes($var);
}

// l'insérer dans la base
$query = sprintf('INSERT INTO `table` SET var="%s"', mysql_real_escape_string($var));
query($query);

// la récupérer et l'afficher
$query = 'SELECT var FROM `table` WHERE id="1"';
$var = stripslashes(query_var($query));
echo $var;

Bilan des niveaux d'échappement:
Départ: 0.
Mysql_real_escape_string (+1), 1.
Interprétation par MySQL (-1), 0.
Conclusion: le résultat est fixe et correspond à la valeur originale.
Modifié par Necromantik (22 Feb 2008 - 18:49)
Administrateur
Virtuellement, et si la configuration de PHP est propre (ie : pas de magic quotes), on ne devrait jamais avoir besoin de se servir de stripslashes. Un seul appel à mysql_real_escape_string par chaîne concernée, sans apparition de \' superflus.
magic_quotes_gpc() est à ON chez moi mais j'utilise mysql_real_escape_string() pour insérer et mettre à jour mes données dans ma DB.

Que faire pour ne plus avoir de backslash car dans ma DB, après insertion ou mise à jour, on retrouve bel et bien des backslashes !
Ok, je pense avoir bien cerné le truc, c'est quasiment résolu mais il me reste une dernière question.

Est-ce que dans la DB, je dois avoir des backslashs devant mes apostrophes ou non ?
J'arrive après la bataille mais je vais répondre quand même:

Alphonse a écrit :
Que faire pour ne plus avoir de backslash car dans ma DB, après insertion ou mise à jour, on retrouve bel et bien des backslashes !

Il faut ajouter un test lors de la récupération de la variable qui effectue un stripslashes() au cas ou magic_quotes est activé (on peut aussi fait un stripslashes() arbitraire mais le code n'est plus portable).

Alphonse a écrit :
Est-ce que dans la DB, je dois avoir des backslashs devant mes apostrophes ou non ?

Non, ils n'auraient aucune utilité.
Necromantik a écrit :
Il faut ajouter un test lors de la récupération de la variable qui effectue un stripslashes() au cas ou magic_quotes est activé.
Oui, c'est ce que j'ai fait.
function no_slashes($string) {
	if(1 === get_magic_quotes_gpc())
		return stripslashes($string);
	else
		return $string;
}