Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème caractères non utf8 import fichier csv

Sujet résolu
    30 janvier 2019 à 10:38:27

    Bonjour,

    Je cherche à importer un fichier csv en php, mon script fonctionne très bien la n'est pas le soucis, mais quand j'affiche ma requête SQL je m'aperçois que le fichier csv n'est pas encodé en utf8 et donc ma requête plante.

    Comment faire pour changer ça sur ma requête ?

    Merci d'avance de vote réponse ! 

    • Partager sur Facebook
    • Partager sur Twitter
      30 janvier 2019 à 11:43:05

      Qu'est-ce que "ça" ?

      Solutions :

      1. tu réencodes ce que tu lis de ton CSV en UTF-8 (iconv) (entre le fgetcsv et l'insert)
      2. tu changes le jeu de ta connexion PHP/MySQL pour celui de ton CSV (latin1 ?, paramètre charset du DSN avec PDO)

      -
      Edité par julp 30 janvier 2019 à 11:44:07

      • Partager sur Facebook
      • Partager sur Twitter
        31 janvier 2019 à 10:12:55

        J'ai beau essayer avec le iconv rien ne se passe, j'ai toujours les caractères 
        • Partager sur Facebook
        • Partager sur Twitter
          31 janvier 2019 à 11:44:04

          Tu fais quoi/comment ? (code)

          Tu as pu identifier de manière précise le jeu de caractères dudit fichier ?

          • Partager sur Facebook
          • Partager sur Twitter
            31 janvier 2019 à 12:01:51

            Je récupère les lignes de mon fichier csv et je sépare chaque donnée dans une variable qu'après je met dans une requête SQL.

            Mais du coup j'ai réussi à convertir mon fichier en utf8, mais le utf8 gère pas du tout les accents, au lieu des � j'ai de simples "?" 

            • Partager sur Facebook
            • Partager sur Twitter
              31 janvier 2019 à 12:05:48

              > je sépare chaque donnée dans une variable

              On est d'accord qu'il existe fgetcsv ?

              > le utf8 gère pas du tout les accents

              Bien sûr que si, c'est que tu fais ce qu'il ne faut pas.

              -
              Edité par julp 31 janvier 2019 à 12:09:34

              • Partager sur Facebook
              • Partager sur Twitter
                31 janvier 2019 à 12:31:25

                Le soucis c'est que je ne savais pas faire pour importer un fichier csv vers une BDD donc j'ai pris un script sur internet que j'ai modifié par la suite.

                fgetcsv je viens de tester et il me met plusieurs valeurs dans une même ligne :/

                Edit : En fait je viens de réussir à obtenir ce que je voulais, j'avais laissé le "," à la place de ";" dans le délimiteur.

                Maintenant il me reste encore à régler le problème de ces foutus � :/

                -
                Edité par SkyeZ 31 janvier 2019 à 12:54:00

                • Partager sur Facebook
                • Partager sur Twitter
                  31 janvier 2019 à 13:40:55

                  Toujours pas de code donc je ne vois toujours pas comment t'en dire quoi que ce soit ...

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 janvier 2019 à 13:53:36

                    <?php
                    
                    include("Vues/V_Entete.php");
                    require_once("connect.php");
                    
                     ?>
                     <script type="text/javascript">
                    
                      function extractFilename(path) {
                    if (path.substr(0, 12) == "C:\\fakepath\\")
                    return path.substr(12); // modern browser
                    var x;
                    x = path.lastIndexOf('/');
                    if (x >= 0) // Unix-based path
                    return path.substr(x+1);
                    x = path.lastIndexOf('\\');
                    if (x >= 0) // Windows-based path
                    return path.substr(x+1);
                    return path; // just the filename
                    }
                    
                    
                      </script>
                      <body>
                     <br><br>
                     <script>
                    
                     </script>
                    
                     <form class="" action="" method="post" enctype='multipart/form-data'>
                       <label class="file">Veuillez choisir un fichier à importer : </label>
                       <label for="files" class="label-file">Choisir un fichier</label><output id="list"></output>
                       <input id="files" name="filesImport" class="input-file" type="file" onchange="updateFilename(this.value);size(this.value)"><span id="filename" name="fileName"></span><span id="filesize" name="fileName">&nbsp;&nbsp;</span><br><br><br>
                    
                       <input type="submit" id="sendFile" value="Importer" name="Importer">
                    
                     </form>
                     <script>
                     function updateFilename(path) {
                      var name = extractFilename(path);
                      document.getElementById('filename').textContent = name;
                     }
                    
                     function size(path){
                       var poids = filesize(path);
                       document.getElementById('filesize').textContent = poids;
                     }
                     </script>
                    
                     <?php
                     if (isset($_POST['Importer'])) {
                        extract(filter_input_array(INPUT_POST));
                     $fichier = $_FILES["filesImport"]["name"];
                    $monNewArray = array();
                    $row = 0;
                    if (($handle = fopen($_FILES["filesImport"]["tmp_name"], "r")) !== FALSE) {
                        while (($data = fgetcsv($handle, 100000, ";")) !== FALSE) {
                            $monNewArray[$row] = $data;
                            $row++;
                            // var_dump($data);
                        }
                    
                         fclose($handle);
                    }
                    print_r($monNewArray);
                    }
                    ?>
                    
                     </body>
                     </html>

                    -
                    Edité par SkyeZ 31 janvier 2019 à 13:54:33

                    • Partager sur Facebook
                    • Partager sur Twitter
                      31 janvier 2019 à 14:25:11

                      Il n'y a strictement rien en lien avec une bdd là.

                      Si tu obtiens � via ton print_r c'est que ta page est en UTF-8 quand le fichier importé n'y est pas. Ce qui n'est pas forcément problématique (cf mon premier post, le tout étant d'effectuer la conversion à un moment ou à un autre).

                      -
                      Edité par julp 31 janvier 2019 à 14:26:29

                      • Partager sur Facebook
                      • Partager sur Twitter
                        31 janvier 2019 à 14:31:12

                        Oui ma page est bien en UTF-8, ma base est en utf8_general_CI mais quand je génère le fichier csv à partir du fichier xlsx, je m'aperçois que ce n'est plus en utf-8.

                        Dans ce cas la, une solution pour convertir le fichier csv importé dans mon script php ? Je sais que tu me l'a expliqué plus haut mais ayant déjà essayé je ne dois surement pas bien m'y prendre.

                        -
                        Edité par SkyeZ 31 janvier 2019 à 14:32:22

                        • Partager sur Facebook
                        • Partager sur Twitter
                          31 janvier 2019 à 14:42:36

                          Sous réserve que le CSV soit (systématiquement) encodé en CP1252, ça dépend ce qui est le plus pratique :

                          Si ta connexion à la bdd ne sert qu'à faire l'import, tu la mets en latin1 pour insérer directement, à ce moment-là c'est MySQL qui effectuera les conversions de manières transparentes et le tout est de bien indiquer ce jeu à MySQL pour la connexion

                          $bdd = new PDO('mysql:...;charset=latin1', /* ... */);
                          $bdd-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
                          $stmt = $bdd-&gt;prepare('INSERT INTO table(cola, colb) VALUES(:colA, :colB)');
                          $stmt-&gt;bindParam('colA', $col1);
                          $stmt-&gt;bindParam('colB', $col2);
                          while (list($col1, $col2) = fgetcsv($_FILES['filesImport']['tmp_name'])) {
                              $stmt-&gt;execute();
                          }
                          

                          Sinon

                          Si le fichier CSV est de taille raisonnable, tu convertis directement tout le contenu par un iconv('CP1252', 'UTF-8', file_get_contents($_FILES['filesImport']['tmp_name'])) avant de lire le résultat de cette dernière par str_getcsv

                          $bdd = new PDO('mysql:...;charset=utf8', /* ... */);
                          $bdd-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
                          $stmt = $bdd-&gt;prepare('INSERT INTO table(cola, colb) VALUES(:colA, :colB)');
                          $stmt-&gt;bindParam('colA', $col1);
                          $stmt-&gt;bindParam('colB', $col2);
                          $data = str_getcsv(iconv('CP1252', 'UTF-8', file_get_contents($_FILES['filesImport']['tmp_name'])));
                          foreach ($data as list($col1, $col2)) {
                              $stmt-&gt;execute();
                          }
                          

                          Sinon, il faut convertir chaque ligne lue. Pas compliqué non plus, un coup d'array_map sur le résultat de fgetcsv et c'est réglé.

                          $bdd = new PDO('mysql:...;charset=utf8', /* ... */);
                          $bdd-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
                          $stmt = $bdd-&gt;prepare('INSERT INTO table(cola, colb) VALUES(:colA, :colB)');
                          $stmt-&gt;bindParam('colA', $col1);
                          $stmt-&gt;bindParam('colB', $col2);
                          while ($row = fgetcsv($_FILES['filesImport']['tmp_name'])) {
                              list($col1, $col2) = array_map(function ($v) { return iconv('CP1252', 'UTF-8', $v); }, $row);
                              $stmt-&gt;execute();
                          }
                          

                          PS : voilà pour les différentes approches possibles, je n'ai rien testé

                          -
                          Edité par julp 31 janvier 2019 à 14:54:00

                          • Partager sur Facebook
                          • Partager sur Twitter
                            31 janvier 2019 à 14:51:15

                            J'ai pris la dernière solution, je te remercie beaucoup ça a fonctionné !!! :)
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Problème caractères non utf8 import fichier csv

                            × 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