SQL dans ma boucle For

Résolu
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008 - 15 oct. 2008 à 23:15
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008 - 16 oct. 2008 à 19:19
Bonjour,

Un petit souci inexpliqué, certainement un manque d'expérience de ma part ;)

Je souhaite inséré un enregistrement pour chaque ligne d'article d'un panier dans ma base de donnée SQL et m'envoyer de plus un mail pour chaque enregistrement.
exemple : je reçois une commande de :" 1 paire de chaussettes et une paire de lunettes" soit 2 articles donc 2 enregistrements

Je reçois bien mon mail " 1 paire de chaussettes et une paire de lunettes"

Mais dans ma base de donnée il n'enregistre que le 1er article "1 paire de chaussette"

En clair, la boucle For fonctionne, la condition If dans la boucle for est bien réalisé 2 fois (2 articles = $num_cart_items=2), mais mon insert pour ma base SQL n'est réalisé qu'une fois.

Est ce une question de timing, par exemple la boucle est réalisé plus rapidement que ma requete SQL ? ou ai je fais une erreur dans mon code ?

Je vous remercie d'avance.
Olivier

Voila mon bout de code :

for ($i = 1; $i <= $num_cart_items ; $i++) {
            $itemname = "item_name".$i;
            $itemnumber = "item_number".$i;
            $on0 = "option_name1_".$i;
            $os0 = "option_selection1_".$i;
            $on1 = "option_name2_".$i;
            $os1 = "option_selection2_".$i;
            $quantity = "quantity".$i;
           
            $result = mysql_query("
                INSERT INTO Panier_Commandes(
                    Payer_Email,
                    Item_Name,
                    Quantity,
                    Option_Name_1,
                    Option_Name_2,
                    Option_Selection_1,
                    Option_Selection_2,
                    Txn_ID
                    )
                VALUES(
                    '".$payer_email."',
                    '".$_POST[$itemname]."',
                    '".$_POST[$quantity]."',
                    '".$_POST[$on0]."',
                    '".$_POST[$on1]."',
                    '".$_POST[$os0]."',
                    '".$_POST[$os1]."',
                    '".$txn_id."'
                    )
            ");
               
            if (strlen($itemname) > 1) {
                $mail_Body .= "\n\n" .$i. "e objet en commande: " .$_POST[$itemname]. "\n" . "Numero de l'objet ".$i.": " . $itemnumber . " - " . "Quantite: " .$_POST[$quantity];
            }
        }

12 réponses

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 oct. 2008 à 16:43
Je ne vois pas le problème...

Ta requête ne change pas à chaque boucle for, ce sont les valeur des enregistrements qui ne sont (évidemment) pas les mêmes.
Il suffit de séparer chaque enregistrement par des virgules :

INSERT INTO table (champ1, champ2, champ3) VALUES (valeur1, valeur2, valeur3), (autrevaleur1, autrevaleur2, autrevaleur3), (encoreunevaleur1, encoreunevaleur2, encoreunevaleur3);

Il suffit alors, dans ta boucle for, non pas d'exécuter chaque requête, mais de construire la requête finale en définissant les valeurs.

Bon pis un autre truc : il est INDISPENSABLE de sécuriser les données que tu insères dans ta base de données. Il faut pour cela utiliser la fonction mysql_real_escape_string() sur les variables $_POST avant de les insérer. Cela évite les injections SQL.

Neige

N'hésitez pas à lire la doc de PHP avant de poser des questions triviales...
3
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 oct. 2008 à 19:02
L'avantage (ou pas) des erreurs, c'est qu'elles sont toujours visibles.
Ce que tu peux faire :

//tester le retour de la fonction est le seul moyen de vérifier que ça s'est bien passé.
if(!$res)
      $mail_body .=
'Erreur : ' . mysql_error();

Et t'as l'erreur dans ton mail.

Ordinastie.
3
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 oct. 2008 à 12:06
Salut,

Si je peux me permettre... La commande INSERT en SQL permet d'insérer plusieurs enregistrements. Ce qui est autrement plus rapide que d'exécuter une requête de type INSERT pour chaque...

Neige

N'hésitez pas à lire la doc de PHP avant de poser des questions triviales...
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 15:33
Bonjour,

Je suis au courant qu'on peut enregistrer plusieurs enregistrements à l'aide de INSERT, mais je n'ai pas trouvé d'autre solutions que celle ci, puis que ma requete change avec la boucle For, et de plus je ne connais jamais la fin de ma boucle qui dépend de $num_cart_items.

As tu une autre solution ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sidf Messages postés 1216 Date d'inscription mardi 20 décembre 2005 Statut Membre Dernière intervention 18 octobre 2012 5
16 oct. 2008 à 16:36
bonjour,

il faudrait voir le code du formulaire
comment sont chargées les $_POST ??
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 16:39
Les $_POST sont envoyés de Paypal sur ma page, mais les $_POST sont bon puisqu'ils sont introduit dans $mail_body avec succès.
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 oct. 2008 à 17:59
Bonjour,

En regardant le code comme ça, je ne vois pas de problèmes.
Neige a raison concernant le multi-insert. Tu n'as qu'a construire ta requête dans ta boucle et lancer la requête construite à la fin.

for(
$i = 1;
$i <=
$num_cart_items;
$i++)
{

      //tes assignations de variables
      
      $query_values .=
"(".
$payer_email.
"',
                                 '".
$_POST[
$itemname].
"',
                                 '".
$_POST[
$quantity].
"',
                                 '".
$_POST[
$on0].
"',
                                 '".
$_POST[
$on1].
"',
                                 '".
$_POST[
$os0].
"',
                                 '".
$_POST[
$os1].
"',
                                 '".
$txn_id.
"'), ";
}

//retirer la virgule en trop pour éviter de faire planter la requête à cause du dernier enregistrement
$query_values =
substr(
$query_values, 0, -2);

$query =
"INSERT INTO Panier_Commandes(
                                 Payer_Email,
                                 Item_Name,
                                 Quantity,
                                 Option_Name_1,
                                 Option_Name_2,
                                 Option_Selection_1,
                                 Option_Selection_2,
                                 Txn_ID)
             VALUES " .
$query_values;

$res =
mysql_query(
$query);

//tester le retour de la fonction est le seul moyen de vérifier que ça s'est bien passé.
if(!
$res)

      echo
'Erreur : ' .
mysql_error();

Pour moi, la seule explication est un problème directement lié à l'insertion (surement à cause de guillemets ou d'apostrophes non gérés). Donc protège tes données comme il t'a été conseillé, et teste le retour de l'appel à la requête pour être sur que ça marche comme il faut. Dans le cas contraire, t'auras les informations nécessaires pour corriger le problème.

Ordinastie.
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 18:00
C'est ce que je pensais essayé : Construire ma requete.

Oui je sais qu'il faut sécuriser mes données, je le fais toujours dès que tout fonctionne je rajoute mes protections.

J'essaye, et je te tiens au courant

Merci
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 18:35
Alors là, j'y comprends rien.

J'ai fait comme vous m'avez dis (simplement une légère différence), et je n'ai toujours qu'un seul enregistrement dans ma base de donnée, mais je reçois bien mes lignes venant de $mail_body.
Voila mon code, mais je ne pense pas qu'il y ait une erreur, c'est bizarre :

if ($num_cart_items >=1) {
           
            $query="
            INSERT INTO Panier_Commandes(
                Payer_Email,
                Item_Name,
                Quantity,
                Option_Name_1,
                Option_Name_2,
                Option_Selection_1,
                Option_Selection_2,
                Txn_ID
                )
            VALUES
            ";
               
            for ($i = 1; $i <= $num_cart_items ; $i++) {
                $itemname = "item_name".$i;
                $itemnumber = "item_number".$i;
                $on0 = "option_name1_".$i;
                $os0 = "option_selection1_".$i;
                $on1 = "option_name2_".$i;
                $os1 = "option_selection2_".$i;
                $quantity = "quantity".$i;
           
            $query .="(
                '".$payer_email."',
                '".$_POST[$itemname]."',
                '".$_POST[$quantity]."',
                '".$_POST[$on0]."',
                '".$_POST[$on1]."',
                '".$_POST[$os0]."',
                '".$_POST[$os1]."',
                '".$txn_id."'
            ), ";
               
               
                if (strlen($itemname) > 1) {
                    $mail_Body .= "\n\n" .$i. "e objet en commande: " .$_POST[$itemname]. "\n" . "Numero de l'objet ".$i.": " . $itemnumber . " - " . "Quantite: " .$_POST[$quantity];
                }
            }
            $query = substr($query, 0, -2);
            $select=mysql_query($query);
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 oct. 2008 à 18:40
Tu as testé le retour de la fonction? ($select)

PS: ce test if(strlen($itemname) > 1) sera toujours vrai vu que tu set $itemname à chaque tour de boucle.
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 18:57
Je n'ai pas testé le retour de la fonction select, car la page n'est pas vu, les infos sont envoyés par paypal directement.

Mais il y a toujours la 1ère boucle qui est bien enregistré.

Je travaille dessus pour faire une page de test en dehors de paypal, je regarde le résultat et je vous tiens au courant
0
Const4ntine Messages postés 39 Date d'inscription mercredi 4 juin 2008 Statut Membre Dernière intervention 11 décembre 2008
16 oct. 2008 à 19:19
Quand on a une erreur c'est toujours un petit truc à la con.

J'ai donc vu mon message d'erreur qui était : Duplicate entry '0' for key 1
1062

Je suis donc aller directement dans ma base de donnée, et j'ai vu que incrémentation de ma clé primaire n'avait pas été enregistrer lors de la création de la base de donnée.

En clair, il enregistrait le 1er envoi, avec en clé primaire 0, puis les autres il ne voulait pas car ils avaient la meme clé primaire.

On peut dire que j'aurai passé beaucoup pour pas grand chose, mais il parait que c'est comme ça qu'on apprend.
J'ai tout de meme appris plein de chose en php grace à vous.

Donc c'est avec un grand merci que je vous dis à bientot pour de nouvelle aventure codé ;)
0
Rejoignez-nous