Partage
  • Partager sur Facebook
  • Partager sur Twitter

execute un INSERT INTO d'un array dans un foreach

Sujet résolu
    7 mai 2021 à 13:47:14

    Bonjour,

    Je souhaiterais insérer dans une base 2, 3, 4 ou plus lignes d'un coup. Les données proviennent d'un form. Pour cela j'ai créé un tableau associatif, j'ai preparé mon INSERT INTO mais après je ne sais pas comment faire le EXECUTE dans la boucle foreach.

    Déjà ai-je le droit de faire mon array comme ça : 

    $resultat = array ('detail_partie' => $lastid, $_POST['id_joueur1'] => $_POST['score1'], 'detail_partie2' => $lastid, $_POST['id_joueur2'] => $_POST['score2']);

    Quand je fais un echo dans le foreach ça a l'air correct.

    Voilà le code complet :

    //On crée la partie et on récupère son id
    $req = $bdd->prepare('INSERT INTO plays_parties (partie_jeu, duree_partie, nb_joueurs, evenement, date_partie) VALUES(?, ?, ?, ?, NOW())');
    $req->execute(array($_POST['id_jeu'], $_POST['duree_partie'], $_POST['nb_joueurs'], $_POST['evenement']));
    
    //on affiche le dernier ID, ça fonctionne
    //echo $bdd->lastInsertId();
    $lastid = $bdd->lastInsertId();
    //echo $lastid;
    
    //On ajoute les détails de la partie dans la table detail
    $resultat = $bdd->prepare('INSERT INTO plays_details (detail_partie, detail_joueur, detail_score) VALUES(?, ?, ?)');
    //$req->execute(array($lastid, $_POST['id_joueur1'], $_POST['score1']));
    
    $resultat = array ('detail_partie' => $lastid, $_POST['id_joueur1'] => $_POST['score1'], 'detail_partie2' => $lastid, $_POST['id_joueur2'] => $_POST['score2']);
    
    foreach($resultat as $element)
    {
        echo $element . '<br />'; // affichera $donnees[0], $donnees[1] etc.
        echo '<pre>';
        print_r($resultat);
        echo '</pre>';
    }

    Surtout, je ne sais pas si ce qui est avant le => sera aussi injecté dans la table

    Je nettoierai le code après, pour l'instant je garde tous les comments pour voir comment j'avance. Et j'ajouterai les htmlspecialchars évidemment :)

    Merci



    -
    Edité par bol2ry 7 mai 2021 à 13:49:02

    • Partager sur Facebook
    • Partager sur Twitter
      7 mai 2021 à 13:57:14

      Salut

      Le tableau passé à execute doit avoir pour clés les positions et pour valeurs les… valeurs à insérer. Ce qui implique qu'avec la requête ainsi préparée ligne 11, tu dois l'exécuter une fois par enregistrement souhaité, à chaque fois avec les valeurs correctes.

      Tu aurais une autre possibilité qui serait de construire ta requête préparée en "multipliant" la partie des valeurs ((?, ?, ?), (?, ?, ?), …) autant de fois que d'enregistrement à insérer, mais du coup tu devrais avoir une valeur pour chacun des marqueurs, donc potentiellement dupliquer certaines dans ton tableau.
      Une possibilité pour éviter de devoir dédoubler les valeurs communes à chaque enregistrement : utiliser les marqueurs nommés et activer (je ne sais plus si c'est le cas par défaut) l'émulation des requêtes préparées, ce qui permet de réutiliser un marqueur nommé à plusieurs endroits. En revanche, les clés doivent du coup être les noms des marqueurs.

      • Partager sur Facebook
      • Partager sur Twitter
        7 mai 2021 à 14:12:42

        Salut, merci pour la réponse rapide.

        Exécuter une fois la requête par enregistrement c'est ce que je souhaite mais le problème qui me bloque c'est qu'à la première exécution je veux entrer LastId / id_joueur1 / score1 mais à la deuxième exécution c'est LastId (le même à nouveau) / id_joueur2 / score2 et ainsi de suite et je ne sais pas comment changé ces valeurs entre deux exécutions.

         Tu veux dire que mon array devrait ressembler à ça :

        $resultat = array ('detail_partie' => $lastid, 'detail_joueur' => $_POST['id_joueur1'], 'detail_score' => $_POST['score1'], 'detail_partie2' => $lastid, 'detail_joueur' => $_POST['id_joueur2'], 'detail_score' => $_POST['score2']);
        

        Et du coup à 4 joueurs ça va faire une ligne démente :o

        "potentiellement dupliquer certaines dans ton tableau" certaines valeurs sont dupliquées (lastId justement).

        J'avais pensé à faire ça ((?, ?, ?), (?, ?, ?), … mais pareil, je ne sais pas faire le execute après.

        Quand j'insère une seule ligne ça fonctionne mais dès que dans mon form j'ai 2, 3 ou 4 joueurs ça bloque. Bref je tourne en rond depuis 2 jours sans comprendre comment faire le execute proprement (et surtout pour qu'il fonctionne

        • Partager sur Facebook
        • Partager sur Twitter
          7 mai 2021 à 14:15:20

          J'aimerais voir comment tu génères ton formulaire s'il te plaît. Il y a une manière de faire qui pourrait te simplifier la vie.

          • Partager sur Facebook
          • Partager sur Twitter
            7 mai 2021 à 14:20:51

            Pas de souci parce que là vraiment je lutte :p je suis preneur de tout conseils.

            Voilà le form (exemple pour 2 joueurs) :

            <form action="ajout_test.php" method="post">
                <p>
                    <label for="id_jeu">Nom du jeu</label> :
                        <?php
                        //afficher la liste des jeux dans une liste déroulante
            
                        //récupérer la liste des jeux pour la partie
                        $reponse = $bdd->query('SELECT id_jeu, nom_jeu FROM plays_jeux');
            
                        // On fait une boucle pour lister tout ce que contient la table :
                        echo "<select name='id_jeu'>";
                        while ($donnees = $reponse->fetch())
                            {
                             echo "<option value='".$donnees['id_jeu']."'>".$donnees['nom_jeu']."</option>";
                            }
                        echo "</select>";
                        ?>
            <br />
                    <label for="id_joueur1">Joueur 1</label> :
                        <?php
                        //afficher la liste des joueurs dans une liste déroulante
            
                        //récupérer la liste des joueurs pour le joueur 1
                        $reponse = $bdd->query('SELECT id_joueur, pseudo FROM plays_joueurs');
            
                        // On fait une boucle pour lister tout ce que contient la table :
                        echo "<select name='id_joueur1'>";
                        while ($donnees = $reponse->fetch())
                            {
                             echo "<option value='".$donnees['id_joueur']."'>".$donnees['pseudo']."</option>";
                            }
                        echo "</select>";
                        ?>
                    <label for="score1">Score</label> :  <input type="number" name="score1" id="score1" />
            <br />
                    <label for="id_joueur2">Joueur 2</label> :
                        <?php
                        //afficher la liste des joueurs dans une liste déroulante
            
                        //récupérer la liste des joueurs pour le joueur 1
                        $reponse = $bdd->query('SELECT id_joueur, pseudo FROM plays_joueurs');
            
                        // On fait une boucle pour lister tout ce que contient la table :
                        echo "<select name='id_joueur2'>";
                        while ($donnees = $reponse->fetch())
                            {
                             echo "<option value='".$donnees['id_joueur']."'>".$donnees['pseudo']."</option>";
                            }
                        echo "</select>";
                        ?>
                    <label for="score2">Score</label> :  <input type="number" name="score2" id="score2" />
            <br />
                    <label for="duree_partie">Durée de la partie</label> :  <input type="number" name="duree_partie" id="duree_partie" /><br />
                    <label for="nb_joueurs">nombre de joueurs</label> :  <input type="number" name="nb_joueurs" id="nb_joueurs" /><br />
                    <label for="evenement">Chahaignes 2021</label><input type="hidden" name="evenement" id="evenement" value="Chahaignes 2021" /><br />
                    Date : <?php echo date('d/m/Y h:i:s'); ?><br />
            
                    <input type="submit" value="Envoyer" />
            	  </p>
            </form>



            • Partager sur Facebook
            • Partager sur Twitter
              7 mai 2021 à 14:49:54

              OK, alors on va oublier les nombres directement concaténés dans name et on va utiliser de quoi faire en sorte que tu puisses récupérer des tableaux pour faire une boucle qui va exécuter la requête.

              Je te propose de lire un autre sujet qui, s'il part d'un cas un peu différent, se voit expliquer le même principe que je te recommande.

              -
              Edité par Ymox 7 mai 2021 à 15:11:19

              • Partager sur Facebook
              • Partager sur Twitter
                7 mai 2021 à 15:08:28

                Oui pour les name je ne savais pas faire autrement car on ne peut pas donner le même nom à deux variables. Quelqu'un m'avait dit de faire joueur[] mais je n'ai pas su quoi faire avec ça...

                Je vais lire ton autre sujet ! Merci

                edit : 

                ok donc je pars sur un truc du genre :

                <form action="creation_ok.php" method="post">
                <?php for ($i = 1; $i < 3; $i++): ?>
                <label >Joueur<?php echo $i; ?></label> : <input name="[<?php echo $i; ?>][id_joueur]" />
                <label >Score</label> : <input name="[<?php echo $i; ?>][score]" /><br />
                <?php endfor; ?>
                </form>

                Mais du coup je peux quand même faire un select pour récupérer la liste des pseudo de la base à la place du input ??

                Parce que dès que je passe en select il gueule :p

                <form action="creation_ok.php" method="post">
                <?php $reponse = $bdd->query('SELECT id_joueur, pseudo FROM plays_joueurs');
                    echo "<select name='[ echo $i; ][id_joueur]'";
                    while ($donnees = $reponse->fetch())
                        {
                        echo "<option value='".$donnees['id_joueur']."'>".$donnees['pseudo']."</option>";
                        }
                    echo "</select>"; ?>
                </form>

                Bon et puis même quand je laisse un case à remplir, je n'arrive pas à faire le execute.

                Juste le echo me renvoie le lastid et c'est tout :'(

                //On crée la partie et on récupère son id
                $req = $bdd->prepare('INSERT INTO plays_parties (partie_jeu, duree_partie, nb_joueurs, evenement, date_partie) VALUES(?, ?, ?, ?, NOW())');
                $req->execute(array($_POST['id_jeu'], $_POST['duree_partie'], $_POST['nb_joueurs'], $_POST['evenement']));
                
                //on affiche le dernier ID, ça fonctionne
                //echo $bdd->lastInsertId();
                $lastid = $bdd->lastInsertId();
                //echo $lastid;
                
                //On ajoute les détails de la partie dans la table detail
                $resultat = $bdd->prepare('INSERT INTO plays_details (detail_partie, detail_joueur, detail_score) VALUES(?, ?, ?)');
                //$resultat->execute(array($lastid, $_POST[0], $_POST[1]));
                
                $resultat = array ($lastid, $_POST[0], $_POST[1]);
                
                foreach($resultat as $element)
                {
                    echo $element . '<br />'; // affichera $donnees[0], $donnees[1] etc.
                    
                }







                -
                Edité par bol2ry 7 mai 2021 à 17:02:25

                • Partager sur Facebook
                • Partager sur Twitter
                  11 mai 2021 à 14:05:11

                  Ymox a écrit:

                  OK, alors on va oublier les nombres directement concaténés dans name et on va utiliser de quoi faire en sorte que tu puisses récupérer des tableaux pour faire une boucle qui va exécuter la requête.

                  Je te propose de lire un autre sujet qui, s'il part d'un cas un peu différent, se voit expliquer le même principe que je te recommande.

                  -
                  Edité par Ymox 7 mai 2021 à 15:11:19


                  Bon désolé je n'arrive pas à faire mon execute derrière. Je ne vois pas comment mettre mes $_POST dans le Foreach. Si jamais quelqu'un peut m'aiguiller. Merci

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 mai 2021 à 14:09:39

                    C'est ça que de mettre un message "Je vais voir", puis d'éditer en mettant des questions parce qu'il n'y a pas eu assez de temps pour remettre un autre message : les questions ne se voient pas  :p

                    bol2ry a écrit:

                    Mais du coup je peux quand même faire un select pour récupérer la liste des pseudo de la base à la place du input ??

                    Je n'y vois pas d'inconvénient.

                    bol2ry a écrit:

                    Parce que dès que je passe en select il gueule

                    […]

                    Bon et puis même quand je laisse un case à remplir, je n'arrive pas à faire le execute.

                    Mais encore ? Si tu te limites à "ça ne marche pas", moi j'aurai tendance à te dire "pourtant ça peut marcher", et on ne sera pas plus avancés.

                    Tu as regardé ce que tu recevais dans $_POST, au moins ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 mai 2021 à 14:26:04

                      Ymox a écrit:

                      C'est ça que de mettre un message "Je vais voir", puis d'éditer en mettant des questions parce qu'il n'y a pas eu assez de temps pour remettre un autre message : les questions ne se voient pas  :p

                      Oui c'est vrai mais au moins ça m'a obligé à chercher pendant 2 jours et à me torturer les méninges au lieu d'attendre une solution :p

                      Pour le select, je demandais car quand je l'ai ajouté de la même manière qu'avant, il plantait mon form. Je pense que je n'ai pas la syntaxe correct, j'ai mis ça "<select name='[ echo $i; ][id_joueur]'"; mais le echo n'est pas de la bonne couleur dans mon editeur.

                      Pour le $_POST, quand je fais ça :

                      $resultat = array ($lastid, $_POST[0]['id_joueur'], $_POST[0]['score']);
                      
                      foreach($resultat as $element)
                      {
                          echo $element . '<br />'; // affichera $donnees[0], $donnees[1] etc.
                          
                      }

                      J'ai n'ai que le $lastid qui s'affiche

                      Désolé de t'embêter à nouveau avec ça

                      Edit : effectivement quand je fais un print_r de $_POST j'ai ça :

                      Array ( [id_jeu] => 2 [duree_partie] => 60 [nb_joueurs] => 2 [evenement] => Chahaignes 2021 )

                      Et donc rien concernant mes joueurs... pourtant je ne vois pas mon erreur dans le form :'(

                      -
                      Edité par bol2ry 11 mai 2021 à 15:26:03

                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 mai 2021 à 15:27:31

                        echo "<select name='[ echo $i; ][id_joueur]'>";

                        PHP n'interprète pas le code PHP dans une chaîne.

                        echo "<select name='id_joueur[]'>";
                        • c'est une concaténation (ou interpolation) qu'il te faut mais indexer explicitement n'est pas nécessaire ici
                        • il manque une partie du nom
                        • il manque le chevron pour terminer la balise select

                        Tu devrais faire un var_dump($_POST) pour vérifier et visualiser ce que tu reçois.

                        -
                        Edité par julp 11 mai 2021 à 15:39:25

                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 mai 2021 à 15:40:00

                          Ok c'est une chose que j'avais omise (d'où la couleur du Echo qui n'était pas bonne). Merci pour ce point.

                          Du coup entre temps comme je ne m'en sortais pas avec le select j'avais fait juste un input mais toujours pas de résultat dans le print_r.

                          C'était faux ça ?

                          <input name="[<?php echo $i; ?>][id_joueur]" />


                          Mince entre temps tu as édité et je n'ai pas tout vu. Il manque une partie du nom ?

                          Désolé je suis vraiment débutant je ne sais pas ce que c'est un var_dump($_POST)

                          -
                          Edité par bol2ry 11 mai 2021 à 15:45:17

                          • Partager sur Facebook
                          • Partager sur Twitter
                            11 mai 2021 à 15:41:14

                            Oui, aussi, tu dois mettre un nom avant le premier [

                            Si tu génères des name tels que, disons name="joueurs[$i][id]" et name="joueurs[$i][score]", ça te permet ensuite d'itérer facilement dessus :

                            if (isset($_POST['joueurs']) &amp;&amp; is_array($_POST['joueurs'])) {
                                foreach ($_POST['joueurs'] as $joueur) {
                                    echo $joueur['id'], ' : ', $joueur['score'];
                                }
                            }
                            

                            -
                            Edité par julp 11 mai 2021 à 15:54:43

                            • Partager sur Facebook
                            • Partager sur Twitter
                              11 mai 2021 à 15:43:16

                              Ça dépend de ce que tu mets dans ton print_r

                              Edit

                              Mmm, ce n'est peut-être pas valide sans rien avant le premier crochet, mais il semble que ça passe.

                              -
                              Edité par Ymox 11 mai 2021 à 15:45:40

                              • Partager sur Facebook
                              • Partager sur Twitter
                                11 mai 2021 à 16:14:07

                                Purée je crois que ça marche !!!

                                Alors en mettant name='id_joueur[]' et name='score[]' Maintenant j'ai ça :

                                Array ( [id_jeu] => 2 [id_joueur] => Array ( [0] => Steeve [1] => Rom1 ) [score] => Array ( [0] => 343 [1] => 345 ) [duree_partie] => 120 [nb_joueurs] => 2 [evenement] => Chahaignes 2021 )

                                Ce qui a l'air vraiment pas mal.

                                En utilisant la proposition de Julp name="joueurs[][id_score]" et name="joueurs[][score] j'ai ça :

                                array(2) { [0]=> string(3) "207" [1]=> array(4) { [0]=> array(1) { ["id_joueur"]=> string(6) "Steeve" } [1]=> array(1) { ["score"]=> string(3) "456" } [2]=> array(1) { ["id_joueur"]=> string(4) "Nico" } [3]=> array(1) { ["score"]=> string(3) "234" } } }

                                Maintenant il faut que je fasse le execute pour rentrer ça dans la table :) Je peux le faire avec un foreach. Par contre avec ce foreach :

                                foreach ($_POST['joueurs'] as $joueur) { echo $joueur['id'], ' : ', $joueur['score'];

                                il me sort un :

                                ID : : score ID : : score

                                du coup ça ne fonctionne pas. Et si en plus je veux ajouter l'ID de la partie à chaque ligne ça me donne

                                IDpartie ID IDpartie score IDpartie ID IDpartie score

                                alors que pour deux lignes je souhaiterais :

                                IDpartie ID score

                                IDpartie ID score

                                -
                                Edité par bol2ry 12 mai 2021 à 0:09:23

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  13 mai 2021 à 10:57:20

                                  Encore moi... décidément ce thread ne veut pas en finir.

                                  J'arrive à récupérer tout ce que je rentre dans le form ça c'est cool. La première table se remplit, ça c'est cool aussi. Et je voudrais remplir la deuxième avec plusieurs lignes (une par joueur d'où le foreach), mais avec le bout de code de julp, j'obtiens ça :

                                  1 : : 3002 : : 4004 : : 200
                                  id : : score id2 : : score2 id3 : : score3

                                  Je ne comprends pas pourquoi il récupère deux fois les " : ". entre chaque variable id_joueur et score.



                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    13 mai 2021 à 11:27:30

                                    > En utilisant la proposition de Julp name="joueurs[][id_score]" et name="joueurs[][score]

                                    Non, il faut que tu mettes la même valeur entre les [] ci-dessus pour faire correspondre les deux via une même clé (noter que j'y avais bien mis $i) sinon comme le montre ton var_dump tu crées un sous-tableau pour chaque élément (au lieu d'avoir les 2 dans le même)

                                    PS : c'est id_joueur pas id_score ?

                                    -
                                    Edité par julp 13 mai 2021 à 11:29:19

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      13 mai 2021 à 13:48:00

                                      ok j'ai compris !

                                      dans mon form j'ai mis name="joueurs[<?php echo $i; ?>][id_joueur]" et name="joueurs[<?php echo $i; ?>][score]"

                                      du coup mon var_dump me donne bien un array par joueur :

                                      array(3) {
                                        [0]=>
                                        array(2) {
                                          ["id_joueur"]=>
                                          string(6) "Steeve"
                                          ["score"]=>
                                          string(3) "300"
                                        }
                                        [1]=>
                                        array(2) {
                                          ["id_joueur"]=>
                                          string(4) "Nico"
                                          ["score"]=>
                                          string(3) "250"
                                        }
                                        [2]=>
                                        array(2) {
                                          ["id_joueur"]=>
                                          string(6) "Steven"
                                          ["score"]=>
                                          string(3) "800"
                                        }
                                      }

                                      il y a id_joueur pour le input (ou select) du joueur et score pour le input du score.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        13 mai 2021 à 13:58:06

                                        Yep, ça devrait être correct (il faut juste remplacer la clé id par id_joueur par rapport au foreach que j'avais proposé)

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          13 mai 2021 à 14:15:56

                                          Oui c'est ce que j'avais fait direct. ça fonctionne bien ! :D <- homme heureux.

                                          Je clos le sujet et je m'attaque à la suite !

                                          Merci !!!

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          execute un INSERT INTO d'un array dans un foreach

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown