IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Warning: get_class() expects parameter 1 to be object, int given


Sujet :

Symfony PHP

  1. #1
    Membre éclairé
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Par défaut Warning: get_class() expects parameter 1 to be object, int given
    Salut à tous,

    Je ne comprends pas pourquoi j'ai cette erreur :

    Warning: get_class() expects parameter 1 to be object, int given
    alors oui, je comprends l'erreur, il veut un objet et je lui donne un entier ok mais j'ai passé 2 heures ce soir dessus sans succès !
    Je veux passer un entier dans la méthode de mon repo et non un objet.

    Repo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        public function unreadCount(int $userId)
        {
            return $this->createQueryBuilder('m')
                ->where('m.recipient', $userId)
                ->groupBy('m.author')
                ->select("m.author, count(m.id) as nb")
                ->andWhere("m.readAt is NULL")
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
     
                //->getArrayResult();
                //->getResult();
        }
    Controller :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
        /**
         * @Route("/inbox/{user}", name="messages_show", methods={"GET"})
         */
        public function show(User $user)
        {
            $message = new Message();
     
            $form = $this->createForm(MessageType::class, $message);
     
            return $this->render('message/show.html.twig', [
                'form' => $form->createView(),
                'users' => $this->r->getMessages($this->getUser()->getId()),
                'user' => $user,
                'messages' => $this->r->getMessagesFor($this->getUser()->getId(), $user->getId()),
                'unread' => $this->r->unreadCount($this->getUser()->getId()),
            ]);
        }
    mon code me semble correct... quelqu'un aurait-il une idée ?

    Je vous remercie.

  2. #2
    Membre Expert
    Avatar de Alexandre T
    Homme Profil pro
    Ingénieur DevOps
    Inscrit en
    Mai 2002
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 214
    Par défaut
    Oui, tu as bien compris l'erreur.

    Option 1 : Tu t'y plies et tu passes l'objet

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function unreadCount(UserInterface $user)
        {
            return $this->createQueryBuilder('m')
                ->where('m.recipient', $user)
                ->groupBy('m.author')
                ->select("m.author, count(m.id) as nb")
                ->andWhere("m.readAt is NULL")
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
     
                //->getArrayResult();
                //->getResult();
        }
    Option 2 : Tu passes l'id que seul l'entité user connait (j'ai bien dit entité et pas table, car oui la table message connais l'user_id, mais après l'ORM l'entité message ne connait que l'objet user, pas la propriété id de l'objet user)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function unreadCount(int $userId)
        {
            return $this->createQueryBuilder('m')
                ->join('m.recipient')            
                ->where('r.id', $userId)
                 ->groupBy('m.author')
                 ->select("m.author, count(m.id) as nb") 
                ->andWhere("m.readAt is NULL") 
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
                   //->getArrayResult();             
                  //->getResult();     
    }
    L'option 1 est une meilleure pratique pratique que l'option 2, car
    • tu te limites à la couche Objet, alors que dans l'option 2, tu t'encombres de la couche "persistance".
    • tu évites une jointure inutile (certes, cette jointure est forcée par l'ORM, le SGBD saurait très bien s'en passer)



    le développeur qui code le contrôleur lira une documentation du repository du genre : Tu dois passer l'objet utilisateur. C'est plus compréhensible que : tu dois me passer un entier. D'ici à ce que le développeur te balance, l'entier du message, que ça marche dans ces tests (ou plutôt qu'il ne voit pas le soucis), y'a pas des kilomètres. Je dis pas que c'est parti en production ce genre de bugs... Je le dis pas...
    Alexandre Tranchant
    Ingénieur DevOps pour le Ministère de l'Écologie
    Retrouvez mes articles sur PHP et Symfony

  3. #3
    Membre éclairé
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Par défaut
    oui je te rejoins la dessus, la meilleure solution est clairement l'option 1.

    j'ai passé l'objet User.

    Code du repo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        public function unreadCount(UserInterface $user)
        {
            return $this->createQueryBuilder('message')
                ->where('message.recipient', $user)
                ->groupBy('message.author')
                ->select("message.author, count(message.id) as nb")
                ->andWhere("message.readAt is NULL")
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
     
                //->getArrayResult();
                //->getResult();
        }
    Code du controller (on sait jamais) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
        /**
         * @Route("/inbox/{user}", name="messages_show", methods={"GET"})
         */
        public function show(User $user)
        {
            $message = new Message();
     
            $form = $this->createForm(MessageType::class, $message);
     
            return $this->render('message/show.html.twig', [
                'form' => $form->createView(),
                'users' => $this->r->getMessages($this->getUser()->getId()),
                'user' => $user,
                'messages' => $this->r->getMessagesFor($this->getUser()->getId(), $user->getId()),
                'unread' => $this->r->unreadCount($user),
            ]);
        }
    et bien sur, l'erreur affichée explique vraiment bien le problème :
    Expression of type 'App\Entity\User' not allowed in this context.
    Expression de type «App\Entity\User» non autorisée dans ce contexte.

    J'ai une question dans un coin de la tête depuis tout à l'heure.. pourquoi dans le controller je mets "User $user" et dans le repo je mets "UserInterface $user" ? la classe User implémente la UserInterface. Il faut mettre l'un ou l'autre

    PS : oui, je ne sais pas pourquoi j'ai loupé ton message hier soir.

  4. #4
    Membre Expert
    Avatar de Alexandre T
    Homme Profil pro
    Ingénieur DevOps
    Inscrit en
    Mai 2002
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 214
    Par défaut
    Citation Envoyé par bndd24 Voir le message
    J'ai une question dans un coin de la tête depuis tout à l'heure.. pourquoi dans le controller je mets "User $user" et dans le repo je mets "UserInterface $user" ? la classe User implémente la UserInterface. Il faut mettre l'un ou l'autre
    Le principe : De préférence on passe toujours l'interface, comme cela si tu crées une autre classe (classe étudiant, ou classe professeur, etc) qui implémente l'interface, tu n'auras pas à changer ton code.

    En revanche, dans le cas d'un repository, c'est plus discutable, on peut très bien comprendre que tu passes l'entité dont tu as besoin pour la jointure.
    Alexandre Tranchant
    Ingénieur DevOps pour le Ministère de l'Écologie
    Retrouvez mes articles sur PHP et Symfony

  5. #5
    Membre éclairé
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Par défaut
    oui toujours l'interface avant.

    en tout cas User ou UserInterface il me sort la même erreur depuis plus d'une semaine

    J'ai beau regardé mon code ligne par ligne que je ne trouve pas le problème.

    peut-être passer par une requête native ? et non avec le createQueryBuilder.

  6. #6
    Membre Expert
    Avatar de Alexandre T
    Homme Profil pro
    Ingénieur DevOps
    Inscrit en
    Mai 2002
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 214
    Par défaut
    Je t'ai mal conseillé, j'ai dû répondre un peu vite

    ->where('r.id', $userId) <== ça ne peut pas marcher, il faut passer un paramètre !

    OPTION1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public function unreadCount(UserInterface $user)
        {
            return $this->createQueryBuilder('m')
    
    
                ->select("m.author, count(m.id) as nb")
                ->where('m.recipient = :recipient')            
                ->andWhere("m.readAt is NULL") 
                ->groupBy('m.author')
                ->setParameter('recipient', $user)
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
                  //->getArrayResult();             //->getResult();     }
    OPTION2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function unreadCount(int $userId)
        {
            return $this->createQueryBuilder('m')
                ->join('m.recipient' ,'r') //Le second parametre c'est le nom de l'alias
                ->where('r.id = :recipientId')
                 ->groupBy('m.author')
                 ->select("m.author, count(m.id) as nb") 
                ->andWhere("m.readAt is NULL") 
                ->setParameter('recipientId', $userId)
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
                   //->getArrayResult();             
                  //->getResult();     
    }
    Alexandre Tranchant
    Ingénieur DevOps pour le Ministère de l'Écologie
    Retrouvez mes articles sur PHP et Symfony

  7. #7
    Membre éclairé
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Par défaut
    merci de ton aide.

    J'ai copié les deux options que tu proposes et j'ai eu une erreur :

    l'erreur pour l'option 1 :
    [Erreur sémantique] ligne 0, colonne 9 près de 'author, count (m.id)': Erreur: PathExpression non valide. Doit être un StateFieldPathExpression.

    l'erreur pour l'option 2 :
    [Semantical Error] line 0, col 9 near 'author, count(m.id)': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
    J'ai cherché pourquoi et j'ai rajouté () comme l'explique ce post et la plus d'erreur !

    Voici la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public function unreadCount(UserInterface $user)
        {
            return $this->createQueryBuilder('m')
                ->select("(m.author), count(m.id) as nb")
                ->where('m.recipient = :recipient')
                ->andWhere("m.readAt is NULL")
                ->groupBy('m.author')
                ->setParameter('recipient', $user)
                ->getQuery()->execute(null, Query::HYDRATE_ARRAY);
        }
    J'ai testé dans ma vue twig avec un var dump et j'ai bien un tableau mais pas au format voulu. (au moins la requête en elle même fonctionne... )

    tableau qui sort :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    array:2 [0 => array:2 [1 => "286"
        "nb" => "4"
      ]
      1 => array:2 [1 => "291"
        "nb" => "4"
      ]
    ]
    bon.. j'ai avancé (grâce notamment a ton aide).

    dans cette exemple le 286 et 291 sont les id membre et ils doivent être en clé et les 4 sont le nombre de messages non lu ils doivent être en valeur. alors oui, je peux toujours faire avec dans mon twig mais pas propre du tout.

    J'ai cherché du coté de :
    https://stackoverflow.com/questions/...-hydrate-array
    https://www.php.net/manual/fr/function.array-map.php
    du coté de doctrine les explications sont très flou je trouve :
    https://www.doctrine-project.org/pro...result-formats

    J'ai essayé plusieurs codes et plusieurs changements, soit j'ai des erreurs soit le format ne convient pas non plus. Je ne peux pas croire que doctrine ne possède pas une méthode de sortie pour un tableau simple avec choix des clé/valeur c'est fou !! Je passe à coté de quelque chose mais quoi .... Je ne suis plus très loin du but.

Discussions similaires

  1. Réponses: 0
    Dernier message: 12/03/2019, 11h27
  2. [MySQL] Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in
    Par Sarah sh dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 08/12/2013, 19h12
  3. Réponses: 3
    Dernier message: 04/08/2012, 14h11
  4. [2.x] Warning: strpos() expects parameter 1 to be string, array given in
    Par aitiahcene dans le forum Symfony
    Réponses: 19
    Dernier message: 02/07/2012, 11h56
  5. Réponses: 5
    Dernier message: 14/12/2011, 08h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo