SQL dans ma boucle For [Résolu]

Signaler
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008
-
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008
-
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

Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
17
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...
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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.
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
17
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...
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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 ?
Messages postés
1216
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
18 octobre 2012
5
bonjour,

il faudrait voir le code du formulaire
comment sont chargées les $_POST ??
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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.
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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.
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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);
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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.
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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
Messages postés
39
Date d'inscription
mercredi 4 juin 2008
Statut
Membre
Dernière intervention
11 décembre 2008

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é ;)