Page 1 sur 1

[Résolu] PHP / MySql -> guillemets & I'm not a n00b

Posté : 18 déc. 2007, 18:31
par user541
Les problèmes de guillemets sont fréquents entre PHP et MySql car les débutants confondent les doubles quotes et les single quote. Je n'en suis plus à ce niveau (ou pas? :roll:).

Je travaille sur une grosse application de gestion écrite en PHP 5.2.5 & MySql 5.0.38.
J'utilise des objets.
magic_quotes_gpc est à OFF
magic_quotes_runtime est à OFF
magic_quotes_sybase est à OFF

Et pour compliquer le tout le problème est dans un script AJAX (php appelé par du JS), j'utilise FireBug pour débugger mon application.

D'un côté j'obtient un truc parfaitement fonctionnel, exemple avant le mysql_query :

Code : Tout sélectionner

INSERT INTO utilisateur VALUES('zzzzzzzzzzzzz','f72a9822b90d343cf25d93128bb445e7','AMELIE L\'ACCENT','mais\'grumpgh','Mlle','centre',94);
On remarquera les protections. L'insertion dans la BDD fonctionne, etc... \o/

D'un autre côté, pour une table différente, j'ai (toujours avant le mysql_query) :

Code : Tout sélectionner

INSERT INTO communication VALUES('','nicole','nicole','2007-12-18 16:40:12','mail','Annulation d\'une affiliation','encore un acc\'ent');
Et... cela m'insère les backslashs dans la BDD !??!
Les tables sont sur la même base, avec le même type de données (varchar(250) ou text le tout en latin1_swedish_ci).
Je ne comprend pas d'où vient le problème!

La seule différence entre ces deux exemples est la provenance des données :
-pour la table utilisateur les données viennent d'un formulaire utilisateur (input) auquels sont fait des addslashes
-pour la table communication les données viennent de la base de données elle-même, il n'y a pas de stripslashes de fait lors de la récupération.
Avant le echo, un addslashes est fait ; cela me semble logique et le echo de la requête le confirme, sinon il y'a une erreur mysql....

Rmq: si je copie la requête affiché depuis firebug dans phpmyadmin, elle marche !?
Est-ce un bug de FireBug qui ne m'afficherait pas un backslash présent ? Je ne penses vraiment pas... car de toute façon sans addslashes la requête échoue.

Le fait de faire un stripslashes lors de la récupération des données ne change rien au schmilblick, je viens de tester rapidement.

:cry:

Quelqu'un peut-il m'éclairer ?

Posté : 18 déc. 2007, 19:22
par Sékiltoyai
Est ce que tu peux nous filer un bout de code qui donnerait ce résultat ?

Posté : 21 déc. 2007, 17:59
par user541
re,

cela ne sert à rien il y'a plusieurs classes et méthodes concernées....

je dont je suis CERTAIN, c'est que parmi ces deux requêtes (affichage juste avt leur mysql_query respectif):

Code : Tout sélectionner

INSERT INTO communication VALUES('', 'nicole', 'nicole', '2007-12-21 16:25:08', 'mail', 'Annulation d\'une affiliation avec un de vos affiliés', 'ererereer', NULL, NULL, 'mail_sms_fornext', '35', '0', '0'); INSERT INTO communication VALUES('', 'nicole', 'nicole', '2007-12-21 16:25:08', 'mail', 'Annulation d\'une affiliation avec un de vos affiliés', 'dsdsdsdsds', NULL, NULL, 'mail_sms_fornext', '35', '0', '0');
la première ne marche pas, la seconde marche :-(
:twisted: :twisted: :twisted:

terrible -_-

Posté : 22 déc. 2007, 11:54
par Berzemus
Hé ben, c'est que ça concerne autre chôse.. format du tableau, traitement des données, config du serveur, va savoir.

Mais c'est que rien qu'avec ça, on va pas trouver.. sauf si c'est une devinette.

Posté : 22 déc. 2007, 12:31
par user541
Hé ben, c'est que ça concerne autre chôse.. format du tableau, traitement des données, config du serveur, va savoir.
Ok c'est un peu la réponse que j'attendais, il faut que je vérifie tout ca une nouvelle fois mais pourtant la structure des tables semble correct, les scripts aussi, c'est vraiment chiant comme problème...
Mais c'est que rien qu'avec ça, on va pas trouver.. sauf si c'est une devinette.
Bien sûr je comprend cela



J'ai fait plusieurs tests et j'ai isolé le soucis sur une seule table, je suis capable de faire fonctionner l'insertion avec une requête dite manuelle, alors que l'insertion effectuée par une requête créée dynamiquement ne marche pas...
Le dernier test fait en date est le suivant :
<?php
	
	...
	...
	...
	
	$requete="INSERT INTO communication VALUES('',
	'".$this->acteur->get_login_utilisateur()."',
	'".$this->destinataire->get_login_utilisateur()."',
	".dateNull($date_communication).",
	'".$this->type_communication."',
	'".$titre_mail."',
	'".$this->msg_communication."',
	".$type_suivi_relance.",
	".$id_suivi_relance.",
	".$type_mail_sms_communication.",
	".$id_mail_sms_communication.",
	'".$this->traitement_communication."',
	'".$this->is_sms_facturable."');";
	
	echo "_______________________________________________________________________________<br/>";
	print_r($requete);
	
	mysql_query($requete) or die('Erreur insertion communication'); // je me retourve avec un backslashe dans la bdd pour le champ correspondant à la variable $titre_mail
	$this->id_communication=mysql_insert_id();
	
	
	
	
	$marche="Annulation d\'une affiliation avec un de vos affiliés";
	if(strcmp($titre_mail, $marche) == 0)
		echo 'PAREIL !'; // affiche ceci, donc $titre_mail == $marche
	else
		echo 'PAS PAREIL !';
	
	// test 'manuel'
	$reqi="INSERT INTO communication VALUES('',
	'".$this->acteur->get_login_utilisateur()."',
	'".$this->destinataire->get_login_utilisateur()."',
	".dateNull($date_communication).",
	'".$this->type_communication."',
	'".$marche."',
	'dsdsdsdsds',
	".$type_suivi_relance.",
	".$id_suivi_relance.",
	".$type_mail_sms_communication.",
	".$id_mail_sms_communication.",
	'".$this->traitement_communication."',
	'".$this->is_sms_facturable."');";
	
		
	echo "_______________________________________________________________________________<br/>";
	print_r($reqi);
	
	mysql_query($reqi) or die(mysql_error()); // insère proprement dans la BDD (pas de backslashe en trop)

?>
Chié non ? :cry:

A titre personnel je préfère les single quote, le code ci-dessus est fait avec des double-quote dans un soucis de debugage.

Une autre idée ?

Posté : 22 déc. 2007, 13:22
par Aureusms
Est ce que le serveur voit bien un quote et pas son équivalent HTML ou qqchose comme cela (pas un quote mais un autre guillemet) ? Et donc ne le protège pas car il n'a pas besoin de le protéger.

Posté : 22 déc. 2007, 13:24
par user541
=> comment le tester ??!


si j'enlève le backslashe dans $marche le mysql_query échoue...

Posté : 22 déc. 2007, 13:28
par Aureusms
Je pense que tu as fais un echo pour avoir cela ?

Code : Tout sélectionner

INSERT INTO utilisateur VALUES('zzzzzzzzzzzzz','f72a9822b90d343cf25d93128bb445e7','AMELIE L\'ACCENT','mais\'grumpgh','Mlle','centre',94);
Edit : trop vite posté lol

Essaye de le remplacer par l'équivalent HTML via str_replace mais cela confirme si mysql_query echoue... :tir2: :tir2: :tir2:

Posté : 22 déc. 2007, 13:37
par Aureusms
=> comment le tester ??!


si j'enlève le backslashe dans $marche le mysql_query échoue...
Bon une petite question (je ne suis pas expert mais cela m'interroge). Dans $titre_mail dans le premier essai c'est là qu'il faudrait savoir s'il s'agit d'un quote. Car je suis d'accord avec toi si tu l'enlèves de $marche cela ne peut pas marcher.

Posté : 22 déc. 2007, 15:00
par user541
euh ouais pardon ! c'est dans $test_mail que j'ai essayer d'enlever le backslashe, simplement en enlevant le addslashes mis en place.
Normal puisque :

Code : Tout sélectionner

INSERT INTO communication VALUES('', 'nicole', 'nicole', '2007-12-22 13:58:31', 'mail', 'Annulation d'une affiliation avec un de vos affiliés', 'blabla', NULL, NULL, 'mail_sms_fornext', '35', '0', '0');Erreur insertion communication
|*() |*()

Posté : 22 déc. 2007, 22:24
par Berzemus
hmm.. et si tu enlèves purement et simplement tous les single quotes de tes requêtes (en utilistant htmlentities(ENT_QUOTES) par exemple .. de la on pourra y aller pas à pas..

Posté : 14 janv. 2008, 16:13
par user541
j'arrive un peu tard mais les vacances sont passées, tout ca ^^ :D

... et j'ai finalement trouvé le pourquoi du comment (pfiou!) :P

je m'en suis aperçu en modifiant $requete en remplaçant $this->msg_communication par du texte brut, par exemple en remplacant :
 $requete="INSERT INTO communication VALUES('',
    '".$this->acteur->get_login_utilisateur()."',
    '".$this->destinataire->get_login_utilisateur()."',
    ".dateNull($date_communication).",
    '".$this->type_communication."',
    '".$titre_mail."',
    '".$this->msg_communication."',
    ".$type_suivi_relance.",
    ".$id_suivi_relance.",
    ".$type_mail_sms_communication.",
    ".$id_mail_sms_communication.",
    '".$this->traitement_communication."',
    '".$this->is_sms_facturable."');"; 
par
$requete="INSERT INTO communication VALUES('',
    '".$this->acteur->get_login_utilisateur()."',
    '".$this->destinataire->get_login_utilisateur()."',
    ".dateNull($date_communication).",
    '".$this->type_communication."',
    '".$titre_mail."',
    'test de l\'éléphant',
    ".$type_suivi_relance.",
    ".$id_suivi_relance.",
    ".$type_mail_sms_communication.",
    ".$id_mail_sms_communication.",
    '".$this->traitement_communication."',
    '".$this->is_sms_facturable."');"; 
Et à ma grande surprise, malgré l'affichage correct de la requête par le print_r($requete), l'enregistrement inséré ne contenait pas "test de l'éléphant" mais le contenu de $this->msg_communication !?!!?

Et tout c'est éclairci quand le concepteur d'une des classes du site ma indiqué qu'il faisait un UPDATE rapidement après le INSERT........
En fait tout mon code était nickel... mais le update effectué derrière rajoutait des backslashes via un addslashes() inutile :twisted:

Ce qui explique aussi pourquoi beaucoup de mes tests me semblait foirés... je devenait fou !

Bref soucis résolu, je suis bien content !
L'erreur est toujours humaine :wink: