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

Langage PHP Discussion :

array_map(str_getcsv..) m'a piégé


Sujet :

Langage PHP

  1. #1
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut array_map(str_getcsv..) m'a piégé
    Bonjour,

    mon code lit des fichiers csv et le but est d'en extraire chaque valeur. Or le comportement de mon code diffère selon le délimiteur utilisé dans le fichier csv.

    Mon code :
    Code php : 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
    19
    20
     $data = array_map('str_getcsv', file(DIR_ROOT.$upload_dir.DIRECTORY_SEPARATOR.$name)); 
        /* file(xxx) returns an array where each cell is a line of the file passed into parameter.
        array_map executes str_getcsv on each cell of the array returned by file.
        each cell of the array returned by file is a line of the csv file ; str_getcsv puts each elt of the csv file in a cell of an array.*/
     
     
        if (isset($data)) { //only if array $data exists
            //one detects the delimitator
            $Nb_Comas=substr_count($data[0][0], ',');
            $Nb_Semicolons=substr_count($data[0][0], ';');
            if ($Nb_Semicolons > $Nb_Comas) $sep=';'; else $sep=',';
     
            $nb_lines_arr=sizeof($data);
            $val="";
            for ($j=1;$j<$nb_lines_arr;$j++) {  // for each line of the array
                $data[$j]=implode($data[$j]); //if several cells in a line, all is concatenated into a unique line
                $val_split=explode($sep,$data[$j]);//creation of the array $val_split (each cell is a data of the CSV file)
                var_dump($val_split);                   
            }
        }

    Le csv de test initial avait ; comme séparateur et tout allait bien. Ensuite, j'ai testé avec le même csv sauf que le séparateur était une virgule et patatras.
    str_getcsv selon la doc analyse une chaîne de caractères représentant des champs au format CSV et retourne un tableau contenant tous les champs lus.
    C'est bien le cas si le délimiteur est un ; mais pas si c'est ,

    var_dump de la ligne 18
    avec ;
    array (size=23)
    0 => string 'SESA100008' (length=10)
    1 => string '(none)' (length=6)
    2 => string 'Software Engineering' (length=20)
    3 => string 'SESA69723' (length=9)
    4 => string 'CollabNet' (length=9)
    5 => string 'TeamForge_Full' (length=14)
    6 => string '' (length=0)
    7 => string 'TRUE' (length=4)
    8 => string 'Jul 26 2018' (length=11)
    9 => string '' (length=0)
    10 => string '' (length=0)
    11 => string 'France' (length=6)
    12 => string 'Bilhel' (length=6)
    13 => string '---' (length=12)
    14 => string 'Schneider Electric France' (length=25)
    15 => string 'TYS5' (length=4)
    16 => string '' (length=0)
    17 => string 'Industry Business' (length=17)
    18 => string 'CARROS HORIZON' (length=14)
    19 => string '---@schneider-electric.com' (length=42)
    20 => string 'Marc' (length=4)
    21 => string '---' (length=6)
    22 => string '---@schneider-electric.com' (length=34)
    avec ,
    array (size=1)
    0 => string 'SESA100008(none)Software EngineeringSESA69723CollabNetTeamForge_FullTRUEJul 26 2018FranceBilhel---Schneider Electric FranceTYS5Industry BusinessCARROS HORIZON---@schneider-electric.com---...r-electric.com' (length=253)
    Comment faire ? Merci d'avance.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  2. #2
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    septembre 2002
    Messages
    1 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2002
    Messages : 1 403
    Points : 2 501
    Points
    2 501
    Par défaut
    Si tu lis la doc de la fonction str_getcsv tu verras que le séparateur par défaut est la virgule et non pas le point-virgule.

    Si tu avais mis un var_dump($data) tout de suite après l'array_map tu aurais compris. Compris que ton texte avec une virgule fait que $data est un array et que le même texte avec un point-virgule fait que $data est une chaine de caractère et que c'est le reste du code qui fait tout le boulot comme si str_getcsv n'avait servi à rien. Au final pas de piège. Une dernière chose. Ton code ne fonctionne pas s'il n'y a qu'une ligne dans ton fichier.


    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    function str_getcsv_v($text) {
     return str_getcsv($text);
     
    }function str_getcsv_pv($text) {
     return str_getcsv($text,';');
    }
     
    $data = array_map('str_getcsv_pv', file("ton fichier.csv")); 
     
    var_dump($data);
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.
      1  0

  3. #3
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    Merci de me répondre si tard. En fait, après avoir constaté le problème, j'ai mis un var_dump et ai compris la différence, mais n'ai pas encore réussi à faire marcher mon code dans le cas de la virgule. Ca serait quand même plus simple s'il était possible de passer un argument à la fonction str_getcsv quand je la passe à array_map...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  4. #4
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    septembre 2002
    Messages
    1 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2002
    Messages : 1 403
    Points : 2 501
    Points
    2 501
    Par défaut
    Je ne comprends pas ce que tu veux faire.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.
      0  0

  5. #5
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    désolé, je ne suis en mesure de répondre que maintenant !

    Voilà l'idée : je reçois des fichiers csv (dont le séparateur est parfois la virgule et parfois le point-virgule) dont le contenu est une liste de tickets relatants des problèmes rencontrés sur des outils et dont certaines informations doivent être mémorisées en base de données pour interrogation ultérieure (nom de l'outil, date de soumission, status, id du submitter, etc).
    Donc pour faire ça, je réalise un outil (codé en PHP et exécutable avec Wampserver) qui devra lire ces fichiers, et alimenter une bdd MySQL (création ou mise à jour).
    Je suis conscient de pas être précis mais pour pas donner des infos inutiles, merci de me poser des questions.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  6. #6
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    16 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 16 031
    Points : 32 835
    Points
    32 835
    Par défaut
    Bonjour,

    montre des exemples significatifs de fichiers CSV que tu veux traiter.
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images
      0  0

  7. #7
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    J'ai de nouveau ai eu une importante absence !
    Les 2 fichiers comportent des informations identiques ; y a que le séparateur qui change. Dans mon exemple, je ne mets que la ligne d'entête, puis le premier enregistrement.

    fichier csv avec séparateur ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SESAID,ALTERNATEIDS,PLATFORM,PLATFORMOWNER,PUBLISHER,APPLICATIONNAME,HFMCODE,CURRENTLYACTIVE,ACTIVATEDATE,DEACTIVATEDATE,GROUPNAME,OFFICECOUNTRY,FIRSTNAME,LASTNAME,COMPANYNAME,JOBCODE,REPORTINGENTITY,BUSINESSUNITNAME,LOCATION,INTERNETADDRESS,MANAGERFIRSTNAME,MANAGERLASTNAME,MANAGEREMAIL
    SESA100008,(none),Software Engineering,SESA69723,CollabNet,TeamForge_Full,,TRUE,Jul 26, 2018,,,France,Bilhel,xxx,Schneider Electric France,TYS5,,Industry Business,CARROS HORIZON,xxx@schneider-electric.com,Marc,xxx,marc.xxx@schneider-electric.com
    etc
    fichier csv avec séparateur ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SESAID;ALTERNATEIDS;PLATFORM;PLATFORMOWNER;PUBLISHER;APPLICATIONNAME;HFMCODE;CURRENTLYACTIVE;ACTIVATEDATE;DEACTIVATEDATE;GROUPNAME;OFFICECOUNTRY;FIRSTNAME;LASTNAME;COMPANYNAME;JOBCODE;REPORTINGENTITY;BUSINESSUNITNAME;LOCATION;INTERNETADDRESS;MANAGERFIRSTNAME;MANAGERLASTNAME;MANAGEREMAIL
    SESA100008;(none);Software Engineering;SESA69723;CollabNet;TeamForge_Full;;TRUE;Jul 26, 2018;;;France;Bilhel;xxx;Schneider Electric France;TYS5;;Industry Business;CARROS HORIZON;bilhel.xxx@schneider-electric.com;Marc;xxx;marc.xxx@schneider-electric.com
    etc
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  8. #8
    Membre chevronné Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    mars 2008
    Messages
    1 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : mars 2008
    Messages : 1 451
    Points : 1 936
    Points
    1 936
    Par défaut
    As-tu essayé de passer par une librairie, genre CsvLeague (ancien collègue à moi qui l'a faite ^^) ?
    C'est parfois plus simple de passer par un outil tier dans ce genre de cas

    Au pire, il n'y a vraiment que le délimiteur qui change donc c'est peut-être con ce que je vais dire mais ne peux-tu pas simplement regarder le 7e caractère de ta première ligne pour voir s'il s'agit d'une virgule ou d'un point-virgule ?
      0  0

  9. #9
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    avril 2007
    Messages
    8 491
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2007
    Messages : 8 491
    Points : 16 149
    Points
    16 149
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    Ca serait quand même plus simple s'il était possible de passer un argument à la fonction str_getcsv quand je la passe à array_map...
    Il y a un contournement pour ça : array_map peut travailler avec plusieurs tableaux, pourvu qu'ils fassent la même taille.
    Donc tu pourrais faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $lines = file(DIR_ROOT.$upload_dir.DIRECTORY_SEPARATOR.$name);
    $seps = array_fill(0, count($lines), ";"); // on créé un tableau de point-virgules de la même taille que le tableau à traiter
    $data = array_map('str_getcsv', $lines, $seps);
    Autre possibilité : créer une fonction personnalisée qui encapsule str_getcsv avec le séparateur souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function str_get_csv_pv($str) {
        return str_getcsv($str, ";");
    }
    et utiliser la bonne fonction en fonction du besoin.

    La question c'est : as-tu un moyen de savoir dans quel cas de fichier tu te trouves ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]
      0  0

  10. #10
    Membre expert Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    mars 2009
    Messages
    1 783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : mars 2009
    Messages : 1 783
    Points : 3 745
    Points
    3 745
    Par défaut
    "El delimitator pasa a Patatras"

    Citation Envoyé par laurentSc
    Dans mon exemple, je ne mets que la ligne d'entête, puis le premier enregistrement.

    fichier csv avec séparateur ,
    Code csv : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SESAID,ALTERNATEIDS,PLATFORM,PLATFORMOWNER,PUBLISHER,APPLICATIONNAME,HFMCODE,CURRENTLYACTIVE,ACTIVATEDATE,DEACTIVATEDATE,GROUPNAME,OFFICECOUNTRY,FIRSTNAME,LASTNAME,COMPANYNAME,JOBCODE,REPORTINGENTITY,BUSINESSUNITNAME,LOCATION,INTERNETADDRESS,MANAGERFIRSTNAME,MANAGERLASTNAME,MANAGEREMAIL
    ...
    fichier csv avec séparateur ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SESAID;ALTERNATEIDS;PLATFORM;PLATFORMOWNER;PUBLISHER;APPLICATIONNAME;HFMCODE;CURRENTLYACTIVE;ACTIVATEDATE;DEACTIVATEDATE;GROUPNAME;OFFICECOUNTRY;FIRSTNAME;LASTNAME;COMPANYNAME;JOBCODE;REPORTINGENTITY;BUSINESSUNITNAME;LOCATION;INTERNETADDRESS;MANAGERFIRSTNAME;MANAGERLASTNAME;MANAGEREMAIL
    ...
    Si tes fichiers ont un header et que tes noms de champs ont toujours cette tête là (des caractères alphanumériques, pas de caractères spéciaux comme une virgule ou un point virgule), pourquoi ne pas déduire le séparateur de ce header?
    D'autre part, plutôt que de charger ton fichier avec file() qui crée un tableau pour ensuite recréer un autre tableau avec array_map() et pour au final faire une boucle sur chaque ligne, autant lire directement le fichier ligne par ligne en utilisant fgetcsv(), (c'est peut-être moins concis, mais ça te permettra de faire le test du séparateur, et d'économiser de la mémoire).

    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
    19
    20
    21
    22
    23
    24
    25
    26
    if ( false === $handle = fopen(DIR_ROOT.$upload_dir.DIRECTORY_SEPARATOR.$name, 'r') )
        throw new Exception("impossible d'ouvrir le fichier '$name'");
     
    // on récupère le header 
    $buffer = 4096;
     
    if ( false === $header = fgets($handle, $buffer) )
        throw new Exception("Le fichier '$name' est vide");
     
    // on teste différents séparateurs (par ordre de préférence)
    $sep = ','; // par défaut
    $separators = [ ',', ';', '|',  /*etc.*/ ];
     
    foreach ($separators as $separator) {
        if ( strpos($header, $separator) ) {
            $sep = $separator;
            break;
        }
    }
     
    // On peut ensuite boucler sur les lignes et récupérer les champs
    while ( false !== $fields = fgetcsv($handle, $buffer, $sep) ) {
        // les traitements ici
    }
     
    fclose($handle);
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus
      1  0

  11. #11
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    La solution proposée par CosmoKnacki me plaît vu qu'il y a moyen une fois le délimiteur déterminé d'en tenir compte.
    Difficulté supplémentaire (que je viens de découvrir) : petite différence du contenu des colonnes entre les 2 formats : les 2 types de fichier contiennent la même date, mais dans un format différent

    délimiteur ;
    colonne ACTIVATEDATE : Mmm DD , YYYY (le mois est en lettres (en français) et le reste en chiffres)
    colonne DEACTIVATEDATE : vide

    délimiteur ,
    colonne ACTIVATEDATE : Mmm DD
    colonne DEACTIVATEDATE : YYYY

    Voici le code qui me permet de la mettre au format SQL dans le premier cas :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $date1 = \DateTime::createFromFormat('M d, Y', $date);
    return( $date1->format('Y-m-d H:i:s'));
    Ici, la date est dans une seule cellule du fichier csv. Par contre, dans le 2e cas, la date est répartie sur 2 cellules. Du coup, le code actuel retourne 2019-MM-YY hh:mm:ss au lieu de YY-MM-YY hh:mm:ss. Comment puis-je l'adapter ? Je sèche.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  12. #12
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    16 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 16 031
    Points : 32 835
    Points
    32 835
    Par défaut
    Franchement, Laurent.............

    C'est surtout que tu ne réfléchis pas UNE seconde.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if( $sep == ';' ){
    ...
    } else {
    ...
    }
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images
      0  0

  13. #13
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    En fait, mon souci était de savoir quoi mettre dans le else. Mon idée (pas encore eu le temps de la suivre) est dans ce cas de construire une donnée au format du cas 1 (Mmm DD , YYYY).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  14. #14
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    16 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 16 031
    Points : 32 835
    Points
    32 835
    Par défaut
    Et tu ne sais pas concaténer 2 variables ?......
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images
      0  0

  15. #15
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    Si et c'est justement ce que je viens de faire. Me manquait juste l'idée de me ramener au cas qui marche...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

  16. #16
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    septembre 2002
    Messages
    1 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : septembre 2002
    Messages : 1 403
    Points : 2 501
    Points
    2 501
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    La solution proposée par CosmoKnacki me plaît vu qu'il y a moyen une fois le délimiteur déterminé d'en tenir compte.
    Oui mais non. Il suffit que tu aies une , dans un fichier avec séparateur ; et que tu testes le séparateur , en premier pour que ça ne fonctionne pas. L’inverse est aussi vrai.
    Une solution serait de compter les vrais séparateurs. En toute logique leur nombre divisé par le nombre de lignes doit donner un résultat entier.
    Par vrai séparateur je veux dire une , ou une ; ou tout autre caractère qui sépare deux données car on pourrait fort bien avoir une , ou un ; dans une texte. Exemple : Dans "abcd;efg";1233;"xyz" il y a seulement 2 vrais séparateurs.

    Cosmoknacki étant le roi de la regexp nul doute qu’il trouvera le truc pour ne compter que les vrais séparateurs.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.
      0  0

  17. #17
    Membre expert Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    mars 2009
    Messages
    1 783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : mars 2009
    Messages : 1 783
    Points : 3 745
    Points
    3 745
    Par défaut
    Citation Envoyé par badaze
    Cosmoknacki étant le roi de la regexp nul doute qu’il trouvera le truc pour ne compter que les vrais séparateurs.
    Merci du compliment, mais désolé de te décevoir, car mon approche compte sur le fait que les noms de champs de la ligne du header (car on parle bien de fichiers csv muni d'un header), ne contiennent pas de caractères "exotiques" (ou du moins susceptibles d'être utilisé comme délimiteur, ce qui semble un hypothèse raisonnable).
    Autre chose, quand bien même de tels caractères seraient présents dans les noms de champs, on ne pourrait pas y faire grand chose, contre-exemple:
    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    X1,Y1;X2,Y2;X3,Y3
    12,14;3,5;18,1
    3,415;42,78;3,0
    ...
    Dans ce cas, et en l'absence d'autres renseignements, il est impossible de déterminer quel est le séparateur. Pourtant quelque soit le séparateur choisi, le nombre de champs sera le même pour chaque ligne.

    Par contre rien n'empêche avec mon code précédent de compter le nombre de champs à chaque ligne pour vérifier si ce nombre est bien le même que celui du header. Comme une sorte de contrôle de l'intégrité du fichier csv.

    À propos d'une ligne se présentant sous la forme "abcd;efg";1233;"xyz": ce n'est pas un problème car tout l'intérêt d'utiliser str_getcsv ou fgetcsv c'est que contrairement à un simple explode, ces fonctions prennent en compte un caractère de protection qui est " par défaut, donc dans cet exemple le premier ; ne sera pas vu comme un séparateur.
    Si une telle ligne était utilisée comme header, on ne serait pas plus avancé car rien ne prouve que " est bel et bien un caractère de protection (à partir duquel on pourrait déduire quel est le séparateur). La virgule, l'antislash et le double quote sont juste des conventions sur lesquelles on fait le choix de s'appuyer ou pas; csv reste un format flou, relativement clarifié par la pratique qu'on en a.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus
      0  0

  18. #18
    Membre expert

    Homme Profil pro
    Webmaster débutant
    Inscrit en
    octobre 2006
    Messages
    7 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 7 098
    Points : 3 055
    Points
    3 055
    Billets dans le blog
    1
    Par défaut
    En effet, il y a bien des virgules dans les enregistrements, mais pas dans le header...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell
      0  0

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JavaScript] [SRC] array_map() modification de tous les elements d'un array avec une fonction
    Par SpaceFrog dans le forum Contribuez
    Réponses: 0
    Dernier message: 08/07/2009, 14h28
  2. Réponses: 4
    Dernier message: 20/06/2008, 13h56
  3. Array_map en java?
    Par sunp dans le forum Débuter
    Réponses: 3
    Dernier message: 30/04/2008, 21h24
  4. Fonction str_getcsv() inconnue
    Par pc.bertineau dans le forum Langage
    Réponses: 2
    Dernier message: 21/06/2007, 12h13
  5. [Tableaux] Soucis avec array_map
    Par dunbar dans le forum Langage
    Réponses: 18
    Dernier message: 02/09/2006, 09h23

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