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

Langage PHP Discussion :

lecture d'un fichier csv pour mise en bdd


Sujet :

Langage PHP

  1. #1
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut lecture d'un fichier csv pour mise en bdd
    Bonsoir, je travaille depuis un moment sur une application qui lit des fichiers csv (de plusieurs formats possibles (au sens contenu, sachant que le format informatique est le csv)) et ayant pour but de mettre les infos utiles en BDD.
    J'ai adopté une approche orienté-objet, mais moyennement satisfait, je me pose des questions sur mes choix de conception.
    Il y a 2 classes, une pour le parsage du fichier (CSVParser) et l'autre pour la mise en bdd (CSVinBDD). Mon idée est que la première reçoit en entrée le fichier csv et présente en sortie les données au format prêt à être mis en BDD. La seconde reçoit en entrée ces données et ne fait que d'exécuter des requêtes SQL (update ou insert)). Ai-je donné assez d'informations pour obtenir un avis ?
    Si oui, merci de le donner.

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    salut Laurent

    Est-ce que les données parsées suivent-elles toujours la même mise en forme pour la base de données ?

  3. #3
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Merci de me répondre presque une heure avant que je me lève !

    En fait, la mise en forme des données est variable car elle dépend de la nature de ces données (plusieurs exemples : ça peut être une simple chaîne de caractères ou une date ; de plus, je les mets dans plusieurs tables (exemple : dans le csv, on a une colonne country et une colonne region (une region étant un continent !) donc en plus de la table licenses (si le csv contient les données d'une licence), il y a la table country avec 3 colonnes (country_key, country, region) et dans la table licenses , il n'y aura que la clé étrangère country_key)
    et d'ailleurs, certaines ne vont même pas en bdd (mise en forme inutile)

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    donc si je te suis correctement, les traitements diffèrent selon la nature de la colonne extraite du fichier .csv

    Comment je ferai :
    - une classe CSVParser totalement générique qui ne fait que lire un fichier .csv et transforme toutes les lignes en un tableau avec les colonnes nommées
    - Une classe CSVAnalyse qui analyse les données parsées et construit le sql ou la liste de sql qui va bien
    - Une classe CSVImport qui elle ne s'occupe que de la persistance (des échappements, etc) du résultat de CSVAnalyse

    et une dernière classe CSVWorkUnit qui distribue le travail et coordonne tout ça.

  5. #5
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Merci pour ta réponse.
    J'essaie de la comprendre. OK pour les classes CSVParser et CSVAnalyse. La classe CSVImport, elle va bien exécuter les requêtes SQL construites par CSVAnalyse ? (la persistance dont tu parles doit être assurée par PDO, non ?)

    En outre, si on adopte une architecture MVC (c'est mon cas), la classe CSVWorkUnit serait un contrôleur alors que les 3 précédentes appartiennent au répertoire "model", non ?

    Ai-je bien compris ?

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    la vache ! c'est sacrément bien rentré dis donc
    c'est tout bon

  7. #7
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Bon, super. Je tente d'appliquer ça dans la journée (ou d'ici demain, si j'y arrive pas aujourd'hui) et je te tiens au courant.

  8. #8
    Invité
    Invité(e)
    Par défaut


    FrankensteinSc se serait-il transformé en EinsteinSc ???


    Noooon..... Jef Panacloc, SORS DE CE CORPS !!
    (Fais voir tes mains........ Les deux....)

  9. #9
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 241
    Points
    20 241
    Par défaut
    Comment sont gérés tes types ?
    Je m'explique , ton parser te retourne un tableau , comment sait tu que tel ou tel champs doit être tel ou tel type dans ta base ? C'est en fonction du fichier parsé ?

    Si c'est le cas voilà comment je procèderais (peut être que je vais aborder des concepts que tu ne connais pas):

    - Une factory de parser :
    Ce qui veux dire une interface pour imposer un fonctionnement et ensuite un parser par type de fichier
    Un parser renvois un tableau de données correctement formaté et typée

    - Une classe ImportCSV qui à une fonction qui prend en entrée la table concernée et le tableau de données.

    Ce qui donnerais à l'utilisation quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $parser = ParserFactory::get('fichier_type_X'); // J'indique quel type de fichier je vais traiter, pour utiliser le bon parser
    $datas = $parser->parse('myfile.csv'); // retourne quelque chose comme ['id' => 1, 'date'=>'2020-04-06', 'price' : 50]
     
    $import = CSVImport($db);
    $import->into('matable',$datas);
    Le gros intérêt de cette solution c'est que tu peux ajouter/modifier/supprimer des type de fichier csv très facilement sans être certains d'impacter les autres.

    Ceci étant dit ta façon de faire est déjà correct. Il ne faut parfois pas trop chercher a se faire des nœuds au cerveau et savoir rester simple , surtout si ca répond au besoin courant.

  10. #10
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par grunk Voir le message
    - Une factory de parser : Ce qui veux dire une interface pour imposer un fonctionnement et ensuite un parser par type de fichier
    Je t'aime toi
    Je suis les débuts de Laurent dans le vaste monde de la POO et là je dois avouer que l'embarquer sur les chemins tortueux inspirés des concepts des Design Patterns (Factory) est un peu tôt, c'est aller loin pour un p'tit jeune qui débute.

  11. #11
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 241
    Points
    20 241
    Par défaut
    Il demande des avis je lui donne

    C'est aussi pour ca que je pense que sa solution est déjà bien suffisante

  12. #12
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    un p'tit jeune qui débute.
    Ca me fait sourire vu que vous me devez tous le respect et que Grunk est à peine plus âgé que mon fils (un peu quand même).

    T'as raison rawsrc, même si jreaux vient de me rebaptiser en EinsteinSc, les concepts de Grunk sont un peu élevés pour moi...

  13. #13
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Ce nouveau status de EinsteinSc est dur à porter...

    En fait, j'avance très lentement. Je viens seulement de finir la mise au point de la première classe CSVParser et avant de passer à la seconde, j'aimerais avoir un avis sur ce que je viens de faire. Voici le code de la méthode principale de cette classe :
    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
    21
    22
    23
    24
    25
    26
     
    public function parse($handle)
    {
        $data_CSV=self::dataCSV($handle);  /*   This methods returns separator, type of csv file (either license or ticket) and header (first line of the csv
         file) */
        $header=$data_CSV['header'];
     
        $tab_CSV=[];
        $buffer = 4096;
     
        while ($fields = fgetcsv($handle,
            $buffer,
            $this->sep))
        {
            $tab_CSV[]=$fields;
        }
        $column_names=explode($data_CSV['sep'],$header);
        $tab_to_return=[];
        foreach($tab_CSV as $one_line_tab_CSV)
        {
            $tab_to_return[] = array_combine($column_names,
                $one_line_tab_CSV);
        }
     
            return ($tab_to_return);
    } // end of fct parse

  14. #14
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    tu peux poster le code complet de la classe stp

  15. #15
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
     
    <?php
    namespace model;
     
     
    class CSVParser_model
    {
        /**
         * @var
         */
        private $sep;
        /**
         * @var
         */
        private $type_csv;
     
     
    /* Constructor */
    /**
     * CSVParser_model constructor.
     */
    public function __construct()
    {
     
    }   // end __construct
     
     
        /**
         * @param $file
         *
         * @return bool|false|resource
         */public function getHandle($file)
    {
        if (isset($_FILES['file2']))
            if (!$_FILES['file2']["error"]) {
                $upload_dir = 'csv';
                $name=$_FILES['file2']['name'];
     
                if ( false === $handle = fopen(DIR_ROOT.$upload_dir.DIRECTORY_SEPARATOR.$name, 'r') )
                    throw new Exception("impossible to open the file '$name'");
            }
        if (isset($handle))
            return $handle;
        else return false;
    }
        /** This methods returns separator, type of csv file (either license or ticket) and header (first line of the csv
         * file)
         *
         * @param $handle
         *
         * @return array
         */
    public function dataCSV($handle):array
    {
        if (empty($handle)) return false;
     
        if (isset($_FILES['file2']))
            if (!$_FILES['file2']["error"])
                $name=$_FILES['file2']['name'];
     
        // one reads the header
        $buffer = 4096;
     
        rewind($handle); // to put pointer of $handle at the beginning of the file
     
        if ( false === ($header = fgets($handle, $buffer)) )
            throw new Exception("The file '$name' is empty");
     
        // one tests different separators
        $this->sep = ','; // by default
        $separators = [',', ';'];
     
        foreach ($separators as $separator) {
            if ( strpos($header, $separator)> 0) {
                $this->sep = $separator;
                break;
            }
        }   // end foreach
     
        //Remove UTF8 Bom
     
        $header = UtilFct_controller::removeUtf8Bom($header);
     
        $deb_header=substr($header,0,6);
     
     
        if (UtilFct_controller::contains("SESA",$deb_header)) $this->type_csv="licenses";
        else  if (UtilFct_controller::contains("Ticket",$deb_header)) $this->type_csv="tickets";
        else
        {
            $body = new PhpEcho('', ['msg_error' => "this file is neither a licence nor a ticket"]);
            $body->setCode('<p>'.nl2br($body('msg_error')).'<br></p>');
            echo new PhpEcho([DIR_ROOT, 'view Layout.php'], ['body' => $body]);
            exit;
        }
     
        return ['sep'=>$this->sep,'type_csv'=>$this->type_csv,'header'=>$header];
    }
     
     
    public function parse($handle)
    {
        $data_CSV=self::dataCSV($handle);  /* This methods returns separator, type of csv file (either license or ticket)
       and header (first line of the csv file) */
        $header=$data_CSV['header'];
     
        $tab_CSV=[];
        $buffer = 4096;
     
        while ($fields = fgetcsv($handle,
            $buffer,
            $this->sep))
        {
            $tab_CSV[]=$fields;
        }
        $column_names=explode($data_CSV['sep'],$header);
        $tab_to_return=[];
        foreach($tab_CSV as $one_line_tab_CSV)
        {
            $tab_to_return[] = array_combine($column_names,
                $one_line_tab_CSV);
        }
     
            return ($tab_to_return);
    } // end of fct parse
     
    } // end of class

  16. #16
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    salut Laurent,

    j'ai repris intégralement ton code (à un moment je crois que tu t'es paumé dans la logique)
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    <?php
     
    namespace model;
     
    class CSVParser
    {
        /**
         * @var string|false  CSV field separator
         */
        private $separator = false;
        /**
         * @var string|false    CSV Field enclosure
         */
        private $enclosure = false;
        /**
         * @var resource    CSV file handle
         */
        private $handle;
        /**
         * @var int
         */
        private $buffer = 4096;
        /**
         * @var array  CSV columns header
         */
        private $header = [];
        /**
         * @var array   [[header => value]]
         */
        private $data = [];
        /**
         * @var string|false
         */
        private $csv_type = false;
        /**
         * @var array
         */
        private $errors = [];
     
        /**
         * @return array    [header]
         */
        public function header(): array
        {
            return $this->header;
        }
     
        /**
         * @return array    [[header => value]]
         */
        public function data(): array
        {
            return $this->data;
        }
     
        /**
         * @return string|false
         */
        public function CSVType()
        {
            return $this->csv_type;
        }
     
        /**
         * @return bool
         */
        public function isValid(): bool
        {
            return ($this->separator !== false) && ($this->enclosure !== false) && ($this->csv_type !== false);
        }
     
        /**
         * @return array
         */
        public function errors(): array
        {
            return $this->errors;
        }
     
        /**
         * @param string $filepath
         * @param int    $buffer
         * @return array
         */
        public function parse(string $filepath, int $buffer = 4096)
        {
            $this->handle = $this->getFileHandle($filepath);
            $this->buffer = $buffer;
     
            if (empty($this->errors)) {
                $this->detectSyntaxFromHeader();
                $this->detectCSVType();
            } else {
                return; 
            }
     
            if ($this->isValid()) {
                // les en-têtes ont été passés par la fonction detectSyntaxFromHeader()
                // on récupère toutes les données
                while (($row = fgetcsv($this->handle, $this->buffer, $this->separator, $this->enclosure)) !== false) {
                    $this->data[] = array_combine($this->header, $row);
                }
            }
        }
     
        /**
         * @param $filepath
         * @return resource
         */
        private function getFileHandle($filepath)
        {
            $handle = is_file($filepath) ? fopen($filepath, ('r')) : false;
            if ($handle === false) {
                $this->errors[] = "File {$filepath} doesn't exist or unable to open";
            } else {
                return $handle;
            }
        }
     
        private function detectSyntaxFromHeader()
        {
            // on lit jusqu'à la fin de la première ligne
            $row = fgets($this->handle); // doit contenir les en-têtes des colonnes
            if (empty($row)) {
                $this->errors[] = 'The file is empty';
            }
     
            // séparateur
            if (mb_stripos($row, ',') !== false) {
                $this->separator = ',';
            } elseif (mb_stripos($row, ';') === false) {
                $this->separator = ';';
            } else {
                $this->errors[] = 'Unable to detect the CSV field separator';
                return;
            }
     
            // délimiteur de valeur  (ce qu'il y a entre 2 noms de colonne) : "," ou ";" ou ',' ou ';' etc
            $char = mb_substr($row, 0, 1); // premier caractère
            if (($char === '"') && (mb_stripos($row, '"'.$this->separator.'"') !== false)) {
                $this->enclosure = '"';
            } elseif (($char === "'") && (mb_stripos($row, "'".$this->separator."'") !== false)) {
                $this->enclosure = "'";
            } elseif (ctype_alpha($char)) {
                // pas de délimiteur de texte
                // on vérifie que le premier séparateur trouvé est bien entouré de lettres ASCII
                $i = mb_stripos($row, $this->separator);
                if ($i) {
                    $fc = mb_substr($row, $i - 1, 1);
                    $lc = mb_substr($row, $i + 1, 1);
                    if (ctype_alpha($fc) && ctype_alpha($lc)) {
                        $this->enclosure = '';
                    }
                }
            }
     
            if ($this->enclosure === false) {
                $this->errors[] = 'Unable to detect the CSV text enclosure';
                return;
            }
     
            $this->header = explode($this->separator, str_replace($this->enclosure, '', $row));
        }
     
        private function detectCSVType()
        {
            if ( ! empty($this->header)) {
                $col = $this->header[0];
                if (mb_stripos($col, 'SESA') !== false) {
                    $this->csv_type = 'licenses';
                } elseif (mb_stripos($col, 'Ticket') !== false) {
                    $this->csv_type = 'tickets';
                } else {
                    $this->errors[] = 'This file is neither a licence nor a ticket';
                }
            }
        }
    }
    Il faut que tu divises mieux ta façon de penser. Tu dois arriver à découper une tâche complexe en une série de tâches simples, c'est le secret de l'orienté objet.
    Par ailleurs pourquoi es-tu allé me mettre une vue là-dedans et même la gestion des uploads ? Le Parser n'essaie que que de parser un fichier et basta. Il ne s'occupe pas des uploads ou d'un quelconque affichage.
    Le parsage est déjà suffisamment complexe comme ça à lui tout seul, pas la peine de lui filer encore d'autres responsabilités.

    Bref, le parser essaie de se débrouiller tout seul et stocke les erreurs qu'il rencontre.
    C'est au contrôleur à s'assurer que le parser a terminé son travail sans erreurs (c'est le rôle de la fonction ->isValid() du parser) et de passer à la suite, sinon il charge la vue qui affiche les erreurs et l'envoie au client.

    Inspire toi surtout de ce raisonnement et aussi du code (regarde comment j'ai tout divisé en fonctions et blocs de code simples)

    Bon courage pour la suite

  17. #17
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Merci pour le boulot ; je regarderai demain matin, la tête plus claire que ce soir, et je reviendrai avec mes questions.

  18. #18
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Je viens de regarder ton code. J'ai tout compris (heureusement que tu t'es mis à ma hauteur et ne pas pondre du code complexe). Quelques allers-retours sur Google pour trouver le fonctionnement de certaines fonctions PHP a suffi.
    Maintenant, à moi de m'en servir et ma première question arrive. Pour appeler la méthode parse, il faut lui passer notamment l'adresse du fichier : string $filepath. Il y a déjà une classe pour l'upload : CSVUpload_view :
    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
    21
    22
    23
    24
    25
    26
    27
    <?php
    namespace view;
    use vendor\PhpEcho\PhpEcho;
     
    class CSVUpload_view
    {
    // méthode pour uploader un fichier csv depuis le disque dur
     
    public function csv_upload()
    {
    $this->formCsvARMToDb();
     
    }//end csv_upload
     
    public function formCsvARMToDb()
    { 
        $page = new PhpEcho([DIR_ROOT, 'view Layout.php']);
     
        $body = new PhpEcho([DIR_ROOT, 'view FormCsvARMToDb_view.php'], []);
        $page['body'] = $body;
     
        // on renvoie au navigateur la page assemblée
        echo $page;
    }
     
    } // end of class CSVUpload_view
    ?>
    Mon idée est de le faire retourner à la méthode csv_uploaden ajoutant
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private $filepath;
     
    if (isset($_FILES['file2']))
         if (!$_FILES['file2']["error"]) 
        {
                $upload_dir = 'csv';
                $name=$_FILES['file2']['name'];
                $this->filepath=DIR_ROOT.$upload_dir.DIRECTORY_SEPARATOR.$name
        }
        return $this->filepath;

    et
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     public function filepath()
        {
            return $this->filepath;
        }
    est-ce correct ?

  19. #19
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Je sais pas si mon idée est correcte mais elle fonctionne. J'ai pu afficher le chemin du fichier. Cf cette discussion : https://www.developpez.net/forums/d2...emin-l-upload/. Par contre, j'ai continué à utiliser ton code et ça coince dès qu'on veut extraire le handle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     private function getFileHandle($filepath)
        {
            $handle = is_file($filepath) ? fopen($filepath, ('r')) : false;
           echo "<br/>Parser 114 getFileHandle filepath  handle<br/><br/>";var_dump($filepath);echo "<br/>";var_dump
        ($handle);echo  "<br/><br/>";
            if ($handle === false) {
                $this->errors[] = "File {$filepath} doesn't exist or unable to open";
            } else {
                return $handle;
            }
        }
    affiche
    Parser 114 getFileHandle filepath handle

    string(24) "sep_pointvirgule_ARM.csv"
    bool(false)
    C'est quoi le souci ?

  20. #20
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    salut Laurent

    j'ai écrit ça dans mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $handle = is_file($filepath) ? fopen($filepath, ('r')) : false;
    et avec ceci, ça donne quoi ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $handle = is_file($filepath) ? fopen($filepath, 'r') : false;

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/01/2008, 13h48
  2. Réponses: 3
    Dernier message: 03/01/2008, 12h14
  3. pb de lecture dans un fichier CSV
    Par MayOL69bg dans le forum C#
    Réponses: 3
    Dernier message: 23/05/2007, 14h21
  4. Réponses: 3
    Dernier message: 19/05/2007, 17h19
  5. Linges sautées dans "lecture" d'un fichier .csv
    Par Mymi dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 10/08/2006, 20h02

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