Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme requete sql php

    5 avril 2024 à 22:41:13

    Bonjour, je tente de récupérer un contenu sql via une api en php. Ma requête sql fonctionne très bien quand je l'exécute sur mon serveur sql mais quand j'essaie avec ma fonction php, je n'ai aucun retour mais pas d'erreur.

    Voila ma fonction :

    function read_clients() {
        $stmt = $this->conn->prepare(
            "SELECT c.CODE, c.LIBELLE, COALESCE(r.nb_chariot, 0) AS nb_chariot
             FROM client c
             LEFT JOIN (
                 SELECT CODE, MAX(date) AS max_date, nb_chariot
                 FROM ramassage
                 GROUP BY CODE
             ) AS r ON c.CODE = r.CODE
             LEFT JOIN ramassage r2 ON r.CODE = r2.CODE AND r.max_date = r2.date
             ORDER BY c.CODE ASC"
        );
    
        $stmt->execute();
    
        // Vérification des erreurs
        if ($stmt->error) {
            die('Error : ('. $stmt->errno .') '. $stmt->error);
        }
    
        $result = $stmt->get_result();
        $results = [];
        while ($row = $result->fetch_assoc()) {
            $results[] = $row;
        }
    
        // Affichage des résultats pour le débogage
        var_dump($results);
    
        return $results;
    }

    Et voila la partie de mon api concernée :


    case 'read_clients':
    		$clients = $api->read_clients();
    		if (!empty($clients)) {
    			echo json_encode($clients);
    		} else {
    			echo json_encode(['error' => 'Aucune information trouvée pour les clients spécifiés']);
    		}
    		break;


    Quand j'essaie avec postman, j'ai bien l'affichage du echo qui contient toutes les valeurs mais la variable result n'apparait pas et il n'y a aucune erreur. 

    Quand j'ai essayé avec une pagination (sélection des CODE clients entre 2 bornes), ça a fonctionné pour des petits intervalles mais pas pour la table entière.

    Postman renvoie toujours un 200 ok.

    Merci à tous ceux qui prendront le temps de me répondre !

    • Partager sur Facebook
    • Partager sur Twitter
      8 avril 2024 à 8:40:03

      Bonjour, 

      et en essayant directement pour voir ? $this ->conn->query("SELECT etc.") ?

      • Partager sur Facebook
      • Partager sur Twitter
        8 avril 2024 à 18:23:33

        Bonsoir, merci de ta réponse. 

        Même constant sans requête préparée :

        function read_clients() {
            // Exécution de la requête SQL directement avec query
            $query = "SELECT c.CODE, c.LIBELLE, COALESCE(r.nb_chariot, 0) AS nb_chariot
                      FROM client c
                      LEFT JOIN (
                          SELECT CODE, MAX(date) AS max_date, nb_chariot
                          FROM rama
                          GROUP BY CODE
                      ) AS r ON c.CODE = r.CODE
                      LEFT JOIN ramassage r2 ON r.CODE = r2.CODE AND r.max_date = r2.date
                      ORDER BY c.CODE ASC";
        
            // Exécution de la requête et récupération des résultats
            $result = $this->conn->query($query);
        
            // Vérification des erreurs
            if (!$result) {
                die('Error: ' . $this->conn->error);
            }
        
            // Initialisation d'un tableau pour stocker les résultats
            $results = [];
        
            // Boucle à travers les résultats et les stocker dans le tableau
            while ($row = $result->fetch_assoc()) {
                $results[] = $row;
            }
        
            // Affichage des résultats pour le débogage
            var_dump($results);
        
            // Retourner les résultats
            return $results;
        }

        Quand je supprime le vardump, plus rien ne s'affiche en retour dans postman hormis le 200 ok. Par contre, avec le vardump tous les détails s'affiche bien de cette manière :

        array(466) {
        [0]=>
        array(3) {
        ["CODE"]=>
        string(1) "0"
        ["LIBELLE"]=>
        string(0) ""
        ["nb_chariot"]=>
        string(1) "0"
        }
        [1]=>
        array(3) {
        ["CODE"]=>
        string(1) "1"
        ["LIBELLE"]=>
        string(11) "Saint-andre"
        ["nb_chariot"]=>
        string(1) "1"
        }
        ...
        [465]=>
        array(3) {
        ["CODE"]=>
        string(4) "1000"
        ["LIBELLE"]=>
        string(5) "ESSAI"
        ["nb_chariot"]=>
        string(1) "0"
        }
        }
        Sinon, existe il une autre méthode afin de récupérer le contenu de toute la table ?



        -
        Edité par Natha_n 9 avril 2024 à 16:20:30

        • Partager sur Facebook
        • Partager sur Twitter
          9 avril 2024 à 17:50:48

          Bonjour,

          Que donne un var_dump($clients) avant l'encodage en json ?

          • Partager sur Facebook
          • Partager sur Twitter
            9 avril 2024 à 22:18:47

            Bonsoir,

            var_dump($clients) retourne la même chose que le var_dump($result)

            J'ai l'impression que ce post se rapproche un peu de mon problème mais je n'arrive pas bien à cerner la solutions:

            • Partager sur Facebook
            • Partager sur Twitter
              10 avril 2024 à 7:18:03

              Donc ce serait la condition ou json_encode ?

              En essayant avec print_r() et/ou sans la condition ?

              • Partager sur Facebook
              • Partager sur Twitter
                10 avril 2024 à 12:30:17

                Oui tu as raison. C'est l'encodage en json qui pose probleme. Avec le print_r j'ai ce retour :

                Array
                (
                [0] => Array
                (
                [CODE] => 0
                [LIBELLE] =>
                [nb_chariot] => 0
                )

                [1] => Array
                (
                [CODE] => 1
                [LIBELLE] => Saint-andre
                [nb_chariot] => 1
                )
                Mais pour mon utilisation, j'aurais plus besoin d'une liste de ce style : [[CODE, LIBELLE,nb_chariot],...,[CODE, LIBELLE,nb_chariot]]
                L'encodage en json a-t-il un limite particulière ? Car j'ai d'autres fonctions dans le même fichier qui utilisent json et fonctionnent parfaitement.
                J'ai aussi essayé de déplacer l'encodage dans la fonction et le résultat est que $clients en retourné vide dans le case du fichier api

                -
                Edité par Natha_n 10 avril 2024 à 13:09:59

                • Partager sur Facebook
                • Partager sur Twitter
                  10 avril 2024 à 13:34:40

                  Salut

                  Les deux structures que tu mentionnes ci-dessus sont les mêmes, mais exprimées différemment.

                  Si json_encode() ne retourne rien, c'est probablement un souci de jeu de caractères des données qui lui sont demandées d'encoder. Peut-on voir le code qui gère la connexion à ta base de données s'il te plaît ?

                  -
                  Edité par Ymox 10 avril 2024 à 13:39:14

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 avril 2024 à 13:41:59

                    > Si json_encode() ne retourne rien, c'est probablement un souci de jeu de caractères des données qui lui sont demandées d'encoder

                    C'est que ce ne serait pas de l'UTF-8. On peut s'en assurer en vérifiant que json_decode ne renvoie pas false (implique un test explicite === false) ou de mettre un var_dump(json_last_error_msg()); ou, carrément mieux, ajouter JSON_THROW_ON_ERROR en flag/option aux json_encode.

                    La grande question étant de savoir s'il y a un mysqli_set_charset (ou son équivalent OO) pour utf8(mb[34]) quelque part ? Ce qui serait tout de même étonnant parce que tu aurais probablement dû déjà voir que tu avais un problème d'"encodage".

                    -
                    Edité par julp 10 avril 2024 à 18:32:04

                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 avril 2024 à 14:15:01

                      Salut Les deux structures que tu mentionnes ci-dessus sont les mêmes, mais exprimées différemment. Si json_encode() ne retourne rien, c'est probablement un souci de jeu de caractères des données qui lui sont demandées d'encoder. Peut-on voir le code qui gère la connexion à ta base de données s'il te plaît ?

                      Dans ma table la colonne CODE est un entier et LIBELLE est de type varchar en latin1_swedish_ci. Pour le code de connexion à la base de donnée, le voici :

                      dans le fichier connect.php

                      <?php
                      $servername = "localhost";
                      $username = "admin";
                      $password = "admin";
                      $dbname = "tournee";
                      ?>
                      
                      

                      et dans le fichier fonctions.php:

                      <?php
                      require_once('connect.php');
                      
                      class API {
                      
                          private $conn;
                      
                          // Connexion à la base de données
                          function __construct() {
                              global $servername, $username, $password, $dbname;
                              $this->conn = new mysqli($servername, $username, $password, $dbname);
                              if ($this->conn->connect_error) {
                                  die('Error : ('. $this->conn->connect_errno .') '. $this->conn->connect_error);
                              }
                          }


                      Cependant, je ne pense pas que ce soit un problème de connexion car la connexion est bien établie avec mes autres fonctions.

                      > Si json_encode() ne retourne rien, c'est probablement un souci de jeu de caractères des données qui lui sont demandées d'encoder C'est que ce ne serait pas de l'UTF-8. On peut s'en assurer en vérifiant que json_decode ne renvoie pas false (implique un test explicite === false) ou de mettre un var_dump(json_last_error_msg()); ou, carrément mieux, ajouter JSON_THROW_ON_ERROR en flag/option aux json_encode. La grande question étant de savoir s'il y a un mysqli_set_charset (ou son équivalent OO) pour utf8(_mb[34]) quelque part ? Ce qui serait tout de même étonnant parce que tu aurais probablement dû déjà voir que tu avais un problème d'"encodage".



                      Pour ce qui est de l'encodage, effectivement, en ajoutant 

                      try {
                              $json_result = json_encode($results, JSON_THROW_ON_ERROR);
                              return $json_result;
                          } catch (JsonException $e) {
                              die('JSON encoding error: ' . $e->getMessage());
                          }

                      à ma fonction lors de l'encodage, j'ai cette erreur :

                      JSON encoding error: Malformed UTF-8 characters, possibly incorrectly encoded
                      et en ajoutant l'encodage avec la vérification :
                      try {
                          // Encodage des résultats en JSON avec détection d'erreur
                          $json_result = json_encode($results, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE);
                          return $json_result;
                      } catch (JsonException $e) {
                          die('JSON encoding error: ' . $e->getMessage());
                      }
                      

                      tout fonctionne. 

                      Reste plus qu'à trouver quelle ligne de ma table pose problème !

                      Merci à tous !



                      -
                      Edité par Natha_n 10 avril 2024 à 14:22:50

                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 avril 2024 à 14:33:34

                        N'importe quelle ligne de ta table pour laquelle un accent se trouve dans le libellé (ou tout aute caractère "exotique" pour du latin 1) va poser problème. D'ailleurs, comme le souligne julp, tu pourrais l'avoir remarqué avec ledit libellé affiché quelque part sur ton site.
                        Il se peut qu'il n'y ait pas qu'un seul libellé problématique.

                        Si le code de ton site est en UTF-8, il faudrait spécifier le bon jeu de connexion à la base de données et convertir les colonnes pour utiliser de l'UTF-8 aussi. Attention, je ne sais pas si les données sont automatiquement converties suivant la manière de changer le jeu de caractères d'une colonne.

                        -
                        Edité par Ymox 10 avril 2024 à 14:36:56

                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 avril 2024 à 14:55:40

                          > Reste plus qu'à trouver quelle ligne de ma table pose problème !

                          Non, tu n'as pas compris : tu DOIS avant tout indiquer le jeu de caractères de ta connexion MySQL (soit, dans ton cas, vu que tu utilises mysqli, par un mysqli_set_charset ou son équivalent OO) ! Si après cela le contenu de tes tables reste un problème c'est que ta base de données est devenu un "mélange" de plusieurs jeux de caractères à cause de ce manque et il va falloir nettoyer/reprendre tes données mais c'est à voir après. Sans procéder de la sorte, au mieux, tu ne résoudras rien ; au pire, tu vas empirer la situation.

                          > je ne sais pas si les données sont automatiquement converties suivant la manière de changer le jeu de caractères d'une colonne

                          Oui, si jamais il y a du mélange de jeux de caractères (latin1 et utf8 stockés comme du latin1), ce ne serait pas aussi simple.

                          EDIT :

                          > Si le code de ton site est en UTF-8

                          Je n'avais pas vu qu'il était en latin1, si c'est le cas, ça ne sent pas bon, il va y avoir du travail en perspective en fonction du volume de données. Dans le meilleur des cas, le site (ce qui est spécifié en valeur de l'attribut charset de l'entête HTTP Content-Type) n'y est pas, il lui suffirait juste de reconvertir de CP1252 à UTF-8 (après avoir ajouté un mysli_set_charset en latin1) via, par exemple, mb_convert_encoding (pas utf8_encode !), pour les seuls json_encode (mais il serait bon de tout passer en UTF-8 par la suite) => correction, vu que c'est une API, si la seule sortie (réponse) est le json_encode, il reste bien plus simple et efficace de faire un mysli_set_charset en utf8, il n'y aurait alors rien à faire, MySQL ayant ainsi réalisé la conversion CP1252 => UTF-8 pour nous en amont.

                          PS : on peut réaliser plusieurs mysqli_set_charset, si le site est effectivement en CP1252/Windows-1252, on pourrait réaliser un premier mysqli_set_charset global/par défaut au niveau de la connexion en latin1 pour le site que l'on viendrait "écraser" par un autre en utf8 pour les seuls json_encode (juste avant la requête associée) de la partie API de ce même site.

                          -
                          Edité par julp 10 avril 2024 à 16:00:42

                          • Partager sur Facebook
                          • Partager sur Twitter
                            10 avril 2024 à 15:26:24

                            Bien vu julp.

                            Mais je tiens à préciser à tout lecteur attentif : si le code fait partie d'un site qui n'est pas qu'une API, notamment s'il y a un back-end d'administration permettant de faire de la saisie, le souci est effectivement plus profond, et les parties barrées du message ci-dessus ne sont pas anodines.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 avril 2024 à 16:15:26

                              Merci de tous vos conseils ! J'ai donc ajouté la définition du jeu de caractère juste après l'initialisation de la connexion à la base de donnée. Pour ce qui est de la base en elle-même, je suis en train de revoir la structure et nettoyer de mes tables.

                              Ce code n'est pas destiné à un site web mais est seulement utilisé pour du stockage de données pour une autre application.

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Probleme requete sql php

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              • Editeur
                              • Markdown