Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de requête avec un foreach

    21 février 2017 à 17:00:02

    Bonjour,

    J'essaye de récuperer les commentaires d'un épisode.

    Dans mon controleur je fais : 

    // recuperation des commentaires des épisodes
    foreach ($informationSerieEpisode as $episode){
    	$id_episode = $episode['id'];
    	$listeCommentaires = commentaire_Episode($id_episode, $bdd);
    	//$valeur = $_SESSION['commentaires_'.$listeCommentaires[].''] = $listeCommentaires;
    	echo 'valeur de id episode' . $listeCommentaires['idEpisode']. '';
    	echo $listeCommentaires['message'];
    }

    Ma requête  " commentaire_Episode  " : 

    	function commentaire_Episode($id_episode, $bdd){
          $req = $bdd->prepare('SELECT * FROM commentaire WHERE idEpisode = :id_episode');
          $req->bindParam(':id_episode', $id_episode);
          $req->execute();
          $result = $req->fetch();
          return $result;
    
    	}

    Je veux donc parcourir chaque épisode et exécuter la requête pour obtenir tous les commentaires.

    Actuellement, j'ai rentré quelque données dans ma table commentaire : 

    Le problème et que je n'arrive pas à récupérer le message   " LOOOL ", quand je regarde ce que m'a renvoyé la requête, j'obtiens que le 1er message pour IdEpisode 1, alors qu'il doit me renvoyer 2 commentaires.

    Le var_dump ($listeCommentaires) me renvoie : 

    Je vous remercie d'avance ! 

    • Partager sur Facebook
    • Partager sur Twitter
      21 février 2017 à 17:03:49

      Tu ne fais que retourner la première ligne (1 fetch = 1 ligne), retournes plutôt le PDOStatement ($req).

      Et il faut une sous-boucle (foreach) sur $listeCommentaires.

      Mais ce serait peut être mieux de ne faire qu'une requête (les épisodes avec leurs commentaires respectifs via une jointure).

      -
      Edité par julp 21 février 2017 à 17:07:23

      • Partager sur Facebook
      • Partager sur Twitter
        21 février 2017 à 17:07:01

        Bonjour,

        Il me semble qu'il faudrait que tu fasse un fetchAll() au lieu d'un fetch() dans ta fonction "commentaire_episode"

        -
        Edité par duflotf 21 février 2017 à 17:08:00

        • Partager sur Facebook
        • Partager sur Twitter
          21 février 2017 à 17:10:54

          Effectivement, le problème était le fetchAll().

          Concernant la jointure, ça serait plus facile de manier les données épisode / commentaires ? 

          • Partager sur Facebook
          • Partager sur Twitter
            21 février 2017 à 17:15:11

            Non ta jointure me semble correct. C'est un peu bizarre dans l'autre sens. Un commentaire est associé à un épisode. Ce n'est pas l'épisode qui est associé à des commentaires.
            • Partager sur Facebook
            • Partager sur Twitter
              21 février 2017 à 17:24:15

              Comme je n'ai que des commentaires pour les premiers épisodes, cela me met une erreur   "     Undefined offset: 0  "  pour les épisodes qui n'ont pas de commantaires

              Car je fais cela dans le foreach : 

              // recuepration des commentaires des épisodes
              foreach ($informationSerieEpisode as $episode){
              	$id_episode = $episode['id'];
              	$listeCommentaires = commentaire_Episode($id_episode, $bdd);
              	$_SESSION['commentaires_'.$listeCommentaires[0]['idEpisode'].''] = $listeCommentaires;
              
              }
              



              -
              Edité par thomxxx 21 février 2017 à 17:26:06

              • Partager sur Facebook
              • Partager sur Twitter
                21 février 2017 à 17:35:03

                Qu'as-tu modifié dans ta fonction en fin de compte ? Il affiche cette notice parce que l'épisode courant n'a encore aucun commentaire ?

                Tu cherches à faire quoi ? (je ne vois pas trop l'intérêt de les mettre en session)

                -
                Edité par julp 21 février 2017 à 17:36:12

                • Partager sur Facebook
                • Partager sur Twitter
                  21 février 2017 à 18:09:49

                  J'ai mis $req->fetchAll();

                  Je met en session pour pouvoir récupérer les valeurs dans ma vue pour l'affichage, le problème et que la requête va s’exécuter pour chercher des commentaires pour l’épisode 4  etc..   mais il y en a pas alors il me renvoie cette erreur puisque pour faire la session il ne trouve rien.

                  Comment je peux faire pour dire si la requête ne renvoie pas de commentaire alors n’exécute pas le $_SESSION ?

                  -
                  Edité par thomxxx 21 février 2017 à 18:16:25

                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 février 2017 à 18:19:47

                    La session pour passer des données à ta vue ?!? Dans ce cas ce serait plus simple de faire une jointure (épisodes/commentaires) et de lui passer le PDOStatement résultant (sachant qu'ils sont traversables donc itérables - fetchAll c'est bien mais quand c'est maîtrisé)

                    Je ne sais pas trop quoi te dire parce que ça ne me paraît pas partir sur de bonnes bases. Au mieux, là, tu caches l'erreur en vérifiant d'abord si le tableau est vide ou pas :

                    $listeCommentaires = commentaire_Episode($id_episode, $bdd);
                    if ($listeCommentaires) {
                        $_SESSION['commentaires_' . $id_episode] = $listeCommentaires;
                    }
                    

                    -
                    Edité par julp 21 février 2017 à 18:25:07

                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 février 2017 à 18:33:26

                      Je me doute, je sais pas comment faire pour PDOStatement. Je suis partis  sur quelque chose qui fonctionnait mais la je commence à melanger les pinceaux.

                      Car j'arrive plus a bien traiter mes données et je fais des foreach dans des foreach, je suis en train de m'y perdre.

                      Actuellement, pour les épisodes dans les saisons ma vue donne cela : 

                      <?php
                      
                      include('../vue/index.php');
                      
                      $serie = $_SESSION['serie'];
                      $saisons = $_SESSION['saison'];
                      
                      
                      ?>
                      
                        <ul class="collapsible " data-collapsible="accordion">
                      <?php
                      
                      foreach ($saisons as $saison)
                      {
                          $episodes = $_SESSION['episode_'.$saison['id'].''];
                          echo '    <li>
                            <div class="collapsible-header"><i class="material-icons">movie</i>Saison'.' '.$saison['numero_saison'].'</div>
                            <div class="collapsible-body">
                        
                            <table class="bordered highlight"">
                              <thead>
                                <tr>
                                    <th data-field="id">#</th>
                                    <th data-field="name">Titre de l\'épisode</th>
                                    <th data-field="price">Diffusion</th>
                                    <th data-field="price">Synopsis</th>
                                    <th data-field="price">Commentaires</th>
                                </tr>
                              </thead>
                        
                              <tbody>
                              ';
                        
                      foreach ($episodes as $episode) {
                          $commentaires = $_SESSION['commentaires_'.$episode['id'].''];
                      
                          foreach($commentaires as $commentaire){
                            var_dump($commentaire['message']);
                          echo'  <!-- Modal Structure -->
                        <div id="modal1" class="modal">
                          <div class="modal-content">
                            <h4>Modal Header</h4>
                            <p>'.$commentaire['message'].'</p>
                          </div>
                          <div class="modal-footer">
                            <a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Agree</a>
                          </div>
                        </div>';
                      }
                          echo '<tr>
                                  <td>'.$episode['numero_episode'].'</td>
                                  <td>'.$episode['titre'].'</td>
                                  <td>'.$episode['date'].'</td>
                                  <td class="text-overflow: ellipsis">'.$episode['synopsis'].'</td>
                                  <td class="right-align"><i class="small material-icons">comment</i><a class="waves-effect waves-light btn" href="#modal1">Modal</a></td>
                                </tr>';
                            
                      }
                        
                      echo '</tbody>
                            </table>
                            </div>
                          </li>';
                      
                      }
                      
                      ?>
                        </ul>
                        <script>
                        $(document).ready(function() {
                        $('.modal').modal();
                      });
                      
                        </script>

                      Je fais un accordéon qui contient les saisons, dedans je fais un tableau pour chaque épisode ( titre, diffusion etc..) et maintenant dans le tableau je voudrais pour chaque épisode avoir un bouton modal qui fera apparaître une modal et dedans cela contiendra la liste des commentaires.

                      Si, tu as une idée pour que cela soit plus clair, je sais pas trop comment utiliser pour la jointure après pour l'affichage des données.

                      Sur ma page cela ressemble à cela : 

                      -
                      Edité par thomxxx 21 février 2017 à 18:35:14

                      • Partager sur Facebook
                      • Partager sur Twitter
                        21 février 2017 à 19:00:55

                        Tu n'y couperas pas à l'imbrication de foreach de toute façon.

                        Mais pour grouper (sur même saison par exemple), c'est simple il suffit d'un ORDER BY et quand tu itères tu la compares à la précédente pour savoir si elle a changé ou pas (et faire ta petite cuisine en conséquence).

                        Sinon PDOStatement::fetchAll a aussi des options pour grouper (PDO::FETCH_GROUP).

                        Les objets PDOStatement, ce sont les résultats de tes requêtes.

                        Exemple saisons/épisodes :

                        $stmt = $bdd->prepare(<<<'EOS'
                            SELECT * -- à affiner si plusieurs tables ont une colonne du même nom, elles vont s'écraser mutuellement
                        		FROM episodes
                        		JOIN saisons ON episodes.id_saison = saisons.id
                        		WHERE episodes.id_serie = :id
                        		ORDER BY saisons.numero_saison
                        EOS
                        );
                        $stmt->bindValue('id', $_GET['id'], PDO::PARAM_INT);
                        $stmt->execute();
                        
                        // partie "vue"
                        if ($episode = $stmt->fetch()) {
                        	$prev = NULL;
                        	do {
                        		if ($prev != $episode['numero_saison']) {
                        			// changement de saison
                        			if ($prev) {
                        				echo '</li></ul>';
                        			}
                        			printf('<ul><li><p>Saison #%d</p>', $episode['numero_saison']);
                        		}
                        		// affichage de l'épisode
                        		echo '<li>', htmlspecialchars($episode['numero_episode'], ENT_NOQUOTES), ' ', htmlspecialchars($episode['titre'], ENT_NOQUOTES), '</li>';
                        		$prev = $episode['numero_saison'];
                        	} while ($episode = $stmt->fetch());
                        	echo '</li></ul>';
                        } else {
                        	// ça ne correspond pas à une série (ou aucun épisode encore diffusé ?)
                        }
                        

                        Ou :

                        $stmt = $bdd->prepare(<<<'EOS'
                            SELECT saisons.numero_saison, * -- à affiner si plusieurs tables ont une colonne du même nom, elles vont s'écraser mutuellement
                        		FROM episodes
                        		JOIN saisons ON episodes.id_saison = saisons.id
                        		WHERE episodes.id_serie = :id
                        		ORDER BY saisons.numero_saison
                        EOS
                        );
                        $stmt->bindValue('id', $_GET['id'], PDO::PARAM_INT);
                        $stmt->execute();
                        $episodes = $stmt->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP);
                        
                        // partie "vue"
                        if ($episodes) {
                        	foreach ($episodes as $k => $subarray) { // saison
                        		printf('<ul><li><p>Saison #%d</p>', $k);
                        		foreach ($subarray as $episode) { // épisode
                        			echo '<li>', htmlspecialchars($episode['numero_episode'], ENT_NOQUOTES), ' ', htmlspecialchars($episode['titre'], ENT_NOQUOTES), '</li>';
                        		}
                        		echo '</li></ul>';
                        	}
                        } else {
                        	// ça ne correspond pas à une série (ou aucun épisode encore diffusé ?)
                        }
                        

                        Les commentaires, ce serait peut être mieux de les charger à la demande, non ?

                        -
                        Edité par julp 21 février 2017 à 19:02:07

                        • Partager sur Facebook
                        • Partager sur Twitter
                          21 février 2017 à 19:13:45

                          La partie de la requête je le met dans la partie model du MVC ?

                          $episodes va être accessible de partout ? 

                          -
                          Edité par thomxxx 21 février 2017 à 19:20:43

                          • Partager sur Facebook
                          • Partager sur Twitter
                            21 février 2017 à 19:21:26

                            La partie de la requête je le met dans la partie model du MCV ?

                            En l'état, plutôt contrôleur. Sinon il faudrait l'encapsuler dans une méthode.

                            $episodes va être accessible de partout ?

                            Ca dépend de ton code (où est créée la variable, en quoi consiste la vue, comment elle est appelée, etc). Dans un "vrai" MVC, tu devrais avoir un moyen (une méthode) de transférer des données du contrôleur à ta vue.

                            -
                            Edité par julp 21 février 2017 à 19:21:43

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Problème de requête avec 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