Partage
  • Partager sur Facebook
  • Partager sur Twitter

Symfony boucle foreach avec plusieurs tableau

Symfony Boucle foreach avec plusieurs tableau

Sujet résolu
    26 octobre 2021 à 23:23:42

    Bonjour, Bonsoir.

    J'ai commencé à programmer en Symfony sur la version 5.3.9 depuis peu, mon projet est un réseaux social avec un fil d'actualité, j'ai donc crée une table follower pour recensé les comptes suivie par les utilisateur et une table post avec en clé étrangère l'id des poster. Dans mon controller "Post" je récupère les compte suivie par l'utilisateur via l'id de ce dernier, ensuite je fais une boucle foreach pour récupérer les post des compte suivie par l'utilisateur connecté et je l'ai envoie à ma vue, j'ai donc plusieur array qui arrive quand je "dump" ma variable dans ma boucle foreach. Mon problème est que quand je dump ma variable hors de la boucle foreach, il me sort que le dernier array récupérer et écrase les précédente.

    Ma fonction index dans mon controller post : 

            $followUser = $this->repositoryFollow->findByExampleField($login->getId());
            
            foreach($followUser as $key=>$post){
                $postUserFollow = $followUser[$key]->getFollowId();
                $post = $this->repositoryPost->findByExampleField($postUserFollow);
                $key++;
            }
    
            return $this->render('post/index.html.twig', [
                'form' => $form->createView(),
                'posts' => $post
            ]);

    Je pense que l'erreur est bête mais j'avoue ne pas la trouver, même après moulte recherche sur les forum... ^^

    Merci d'avance de votre aide.

    Bonne soirée :).

    -
    Edité par JulienElmon 27 octobre 2021 à 0:36:34

    • Partager sur Facebook
    • Partager sur Twitter
      27 octobre 2021 à 6:50:21

      Bonjour,

      Parler de table et de clefs étrangères indiquent que tu n'as pas bien compris le paradigme de Symfony.

      Le niveau table, clef est du domaine du modèle logique base de données et c'est l'orm qui s'en occupe.

      Symfony travaille à un niveau d'abstraction supérieur : les entités et les relations entre entités ... et c'est fondamentalement différent.

      Donc on pourrait supposer que ton entité User est en relation ManyToMany avec une entité Follower ... mais en fait c'est quoi un Follower sans doute un User donc c'est une relation (au sens Symfony et pas BDD) réflexive ... et ton entité Post est sans doute en ManyToMany ou ManyToOne avec User. Cela dépend qu'elle est le sens fonctionnel de la relation : celui qui a écrit le post ?

      Alors pour en revenir à ton problème, ton code lui aussi ne correspond pas de ce fait à un développement Symfony.

      Déjà il ne faut déjà pas mettre une incrémentation de $key : cela se fait tout seul dans le foreach et c'est du simple php.

      On peut aussi supposer que sur la première ligne tu récupères l'utilisateur courant : alors si c'est le cas ce n'est pas ainsi que l'on fait avec Symfony et un simple $this->getUser(); suffit.

      Une fois que tu as récupéré les followers (il devrait y avoir un s dans ton code) du user, il suffit de transmettre le tableau d'objet à la vue et ensuite de boucler dessus dans la vue. C'est inutile de faire cela dans le contrôleur.

      Au delà du problème ponctuel que tu soumets, le problème est plus global tu n'utilises pas Symfony mais tu fais du php sauce bdd ... faut choisir car Symfony ne te sert pas à grand chose dans ce cas et même va te compliquer la tâche.

      A+

      • Partager sur Facebook
      • Partager sur Twitter
        27 octobre 2021 à 11:41:31

        Bonjour monkey3d, 

        Je suis bien en ManyToOne sur ma table User et Post et tout cela est bien géré par ORM, j'ai encore énormément à apprendre sur Symfony car j'ai encore des réflexe de programmation de PHP ^^. 

        Donc j'ai modifier la premier ligne comme ceci :

        $followsUser = $this->repositoryFollow->findByExampleField($this->getUser());


        Et si j'ai bien compris je n'ai pas besoin de faire de boucle foreach pour pouvoir récupérer les post des utilisateur que mon utilisateur connecté a follow mais juste faire la requête et envoyer le tout à ma vue en utilisant une boucle for avec Twig.

        j'ai donc modifier mon code comme ceci :

                $postUserFollows = $followsUser->getFollowId();
                $post = $this->repositoryPost->findByExampleField($postUserFollows);
        
                return $this->render('post/index.html.twig', [
                    'form' => $form->createView(),
                    'posts' => $post
                ]);

        Maintenant il me sort l'erreur : 

        Call to a member function getFollowId() on array

        Si j'ai bien compris l'erreur, j'appelle une fonction dans mon tableau, ce qui semble impossible 

        • Partager sur Facebook
        • Partager sur Twitter
          27 octobre 2021 à 11:44:27

          Salut

          Vérifie que $followUser[$key] contienne bien ce à quoi tu t'attends, apparemment ce n'est pas le cas.

          • Partager sur Facebook
          • Partager sur Twitter
            27 octobre 2021 à 12:00:56

            Bonjour Ymox, 

            J'ai dump ma variable $followsUser[$key] et j'ai bien ce que je désire, c'est à dire la liste des compte suivie par mon utilisateur connecté.

            EDIT : et je récupère bien mes post enfin le dernier post car les précédent semblent écrasé 

            -
            Edité par JulienElmon 27 octobre 2021 à 12:03:30

            • Partager sur Facebook
            • Partager sur Twitter
              27 octobre 2021 à 12:13:17

              Donc dans $followsUser[$key] tu as un tableau de comptes et non un compte unique sur lequel tu pourrais appeler getFollowId(), justement.

              • Partager sur Facebook
              • Partager sur Twitter
                27 octobre 2021 à 12:22:04

                D'accord je vois, donc il me faudrait une fonction qui récupérer les valeurs directement dans le tableau via la clé du tableau ?
                • Partager sur Facebook
                • Partager sur Twitter
                  27 octobre 2021 à 12:24:35

                  Disons qu'une simple boucle devrait suffire, j'imagine. Ou alors adapter la méthode findByExampleField() (qui a un nom très parlant, au passage) pour qu'elle puisse prendre un tableau aussi.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 octobre 2021 à 13:01:18

                    Ton problème persistant - mais je comprends que ce n'est pas facile de changer le mode de pensée - c'est que tu ne dois pas te fixer sur les id mais sur les objets : c'est à ce niveau que travaille Symfony.

                    Donc en supposant que ta fonction très mal nommée - cf remarque Ymox - sache travailler sur un tableau d'objets tu n'a pas forcément à passer d'abord par récupérer pour chaque objet l'id pour le passer à ta fonction. Tu peux passer directement l'objet à ta fonction et comme dit par Ymox tu utilises une boucle pour les balayer tous.

                    A+

                    -
                    Edité par monkey3d 27 octobre 2021 à 13:02:05

                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 octobre 2021 à 13:37:58

                      Merci monkey3d pour tes conseil :) et j'ai modifier le nom de mes fonctions très mal nommé ^^.

                      Ymox : j'ai donc modifier ma requête dans le repository et je récupère bien seulement mes id de follows,

                      j'ai ensuite fait une boucle for comme ceci :

                              $followsUser = $this->repositoryFollow->findByUserId($this->getUser());
                      
                              for($i = 0; $i <= count($followsUser); $i++){
                                  $post = $this->repositoryPost->findById($followsUser);
                              }
                      
                      
                              return $this->render('post/index.html.twig', [
                                  'form' => $form->createView(),
                                  'posts' => $post
                              ]);

                      Maintenant j'ai une erreur sur ma requête que je comprend à moitié : 

                      An exception occurred while executing 'SELECT p0_.id AS id_0, p0_.author AS author_1, p0_.text AS text_2, p0_.date_created AS date_created_3, p0_.user_id AS user_id_4 FROM post p0_ WHERE p0_.user_id = ?, ?, ?' with params [154, 152, 153]:

                      SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' 152, 153' at line 1

                      Ma requête dans mon PostRepository : 

                          public function findById($value)
                          {
                              return $this->createQueryBuilder('p')
                                  ->andWhere('p.user = :val')
                                  ->setParameter('val', $value)
                                  ->orderBy('p.id', 'DESC')
                                  ->getQuery()
                                  ->getResult()
                              ;
                          }


                      Après quelque recherche sur des forums, j'ai vue que l'erreur pouvait venir de la façon dont j'importe mes valeurs dans la fonction "andWhere".

                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 octobre 2021 à 13:47:11

                        Même problème de mode de pensée : comme tu le vois tu passes à ta fonction de ton repository un tableau de 3 valeurs et donc fatalement tu as une erreur..... puisque il est attendu un seul identifiant.

                        with params [154, 152, 153]


                        Quand tu récupères tes followsUser, tu as un tableau (collection) d'objet donc tu parcours classiquement le tableau avec un foreach et ce sera chaque objet que tu passes à ta fonction de ton repository via son id par un simple :

                        $followUser->getId()

                        Et tu remarques que je n'ai pas mis de s puisque c'est un des objets de ta collection.

                        Nota: le andWhere est inutile puisque tu n'as pas 2 clauses au moins : where suffit.

                        A+

                        -
                        Edité par monkey3d 27 octobre 2021 à 13:56:20

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 octobre 2021 à 14:18:17

                          D'accord donc si je comprend bien, je dois utiliser le foreach sans $key car ses gérer automatiquement par php et dans ma boucle foreach je dois la faire de cette sorte :

                                  foreach($followUser as $post){
                                      $post = $this->repositoryPost->findById($followUser->getId);
                                  }

                          Si je fais ainsi, il me réaffiche l'erreur :

                          Call to a member function getId() on array

                          Désolée j'ai vraiment du mal à utiliser foreach mais je sens que ça commencer à rentrer ^^

                          EDIT : j'ai ducoup changer mon andWhere en Where ^^

                          -
                          Edité par JulienElmon 27 octobre 2021 à 14:20:00

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 octobre 2021 à 14:55:52

                            Non la key n'est pas générer automatiquement par le foreach ! Le foreach pour un tableau prend la clef de l'élément et sa valeur suivant la syntaxe.

                            foreach (iterable_expression as $key => $value){


                            Dans le cas d'un tableau classique c'est souvent un indice qui commence à 0 mais dans le cas d'un tableau associatif c'est un identifiant fourni lors de l'initialisation du tableau (souvent un string).

                            Cela devrait mieux fonctionner :

                            foreach($followsUser as $followUser){
                                $post = $this->repositoryPost->findById($followUser->getId);
                            }

                            Attention au s ... 

                            foreach en php est quasi incontournable à maîtriser.

                            A+

                            • Partager sur Facebook
                            • Partager sur Twitter
                              27 octobre 2021 à 15:24:18

                              Oui je vais continuer à me documenter sur le foreach,

                              j'ai donc effectuer les changement et j'ai cette erreur :

                              Notice: Trying to get property 'getId' of non-object

                              Je sens que j'approche de la solution ^^

                                      foreach($followsUser as $followUser){
                                          $post = $this->repositoryPost->findById($followUser->getId);
                                      }

                              et Question : il n'est pas nécessaire de mettre les "()" après getId dans le foreach ? 

                              • Partager sur Facebook
                              • Partager sur Twitter
                                27 octobre 2021 à 15:29:48

                                il n'est pas nécessaire de mettre les "()" après getId dans le foreach ? 

                                Bien sûr que si ! Quelqu'un t'aurait induit en erreur ? ;)

                                A+

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  27 octobre 2021 à 15:43:32

                                  Je me disais aussi ^^.

                                  Du coup après la modification je retourner à l'erreur précédente qui est : 

                                  Call to a member function getId() on array

                                          foreach($followsUser as $followUser){
                                              $post = $this->repositoryPost->findById($followUser->getId());
                                          }
                                  

                                  Je t'avoue que je mouline dans la semoule la ^^' 

                                  EDIT : Ok je crois avoir compris ^^.

                                  Quand je tourne mon code comme ceci : 

                                          foreach($followsUser as $followUser){
                                              $post = $this->repositoryPost->findById($followUser);
                                          }

                                  An exception occurred while executing 'SELECT p0_.id AS id_0, p0_.author AS author_1, p0_.text AS text_2, p0_.date_created AS date_created_3, p0_.user_id AS user_id_4 FROM post p0_ WHERE p0_.user_id = ? ORDER BY p0_.id DESC' with params [154]:

                                  SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

                                  L'erreur m'indique que ça bug à la première boucle, mais cela veut dire que ma boucle fonctionne bien (si je ne me trompe pas).

                                  Du coup je n'ai plus qu'a régler cette erreur ^^.



                                  -
                                  Edité par JulienElmon 27 octobre 2021 à 16:18:48

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    27 octobre 2021 à 16:17:05

                                    Ah bah oui ta fonction 

                                    $followsUser = $this->repositoryFollow->findByUserId($this->getUser());

                                    elle retourne quoi ? sans doute un tableau de tableau et non un tableau d'objets.

                                    Juste après mettre un dd pour voir la structure de $followsUser.

                                    A+

                                    -
                                    Edité par monkey3d 27 octobre 2021 à 16:32:58

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      27 octobre 2021 à 16:25:04

                                      $followsUser =

                                      PostController.php on line 58:
                                      array:3 [▼
                                        0 => array:1 [▼
                                          "follow_id" => 154
                                        ]
                                        1 => array:1 [▼
                                          "follow_id" => 152
                                        ]
                                        2 => array:1 [▼
                                          "follow_id" => 153
                                        ]
                                      ]


                                      Effectivement je fais des tableau dans mes tableau ^^', donc je pense que je dois modifier ma fonction findByUserId()

                                      -
                                      Edité par JulienElmon 27 octobre 2021 à 16:29:14

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        27 octobre 2021 à 16:34:41

                                        C'st sûr que cela ne sert pas dans ton cas de retourner un tableau de tableau avec un seul élément !

                                        Tu es proche ! ;)

                                        A+

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          27 octobre 2021 à 17:55:05

                                          Je demande un indice ^^.

                                          Est-ce que la solution se trouve dans la modification de ma fonction findByUserId() ou alors se trouve à l'intérieur de ma boucle foreach ^^.

                                          EDIT : j'avance enfin ^^, quand j'enlève mon select dans ma requete qui se trouve dans mon FollowRepository, je n'ai plus qu'un tableau. VICTOIRE ^^, par contre je reviens à mon premier problème, je n'ai que le dernier résultat qui s'affiche et les donnée précédente son écrasé ...

                                          -
                                          Edité par JulienElmon 27 octobre 2021 à 19:41:48

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            27 octobre 2021 à 20:02:17

                                            Si tu parles de cela :

                                            foreach($followsUser as $followUser){
                                                $post = $this->repositoryPost->findById($followUser);
                                            }

                                            Oui c'est normal tu te retrouves avec la dernière valeur de ta boucle puisque tu écrases à chaque passage $post précédent.

                                            Il faut donc faire :

                                            $posts = [];
                                            foreach($followsUser as $followUser){
                                                $posts[] = $this->repositoryPost->findById($followUser);
                                            }

                                            A+



                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              27 octobre 2021 à 20:21:55

                                              D'accord mon erreur était tellement bête ^^.

                                              Un gros merci a toi monkey3d tu m'a énormément aider et tes conseil on été très précieux et merci à toi aussi Ymox ^^, vous êtes géniaux ^^.

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Symfony boucle foreach avec plusieurs tableau

                                              × 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