[RESOLU] Parser un répertoire de fichiers DATA pour intégration MySQL

Eléphant du PHP | 103 Messages

07 oct. 2013, 17:04

Bonjour!
Bon j'en suis la et j'avance pas trop mal :
try {
    // connexion
    $pdo = new PDO('mysql:host=localhost;dbname=labase', 'PDO', '290585');
    $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
    $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);

    $dir = new DirectoryIterator(dirname(__FILE__) . '\AVANT');  
    foreach ($dir as $fileinfo) {
        if (!$fileinfo->isDot() && $fileinfo->isFile() && $fileinfo->getExtension() == 'data') {
            //rename("./AVANT/$fileinfo", "./PENDANT/$fileinfo");
            echo 'parse du fichier : '.$fileinfo->getFilename().'<br />';
            $tabFile = file($fileinfo->getPathname());
            preg_match('/^fic(\d+)-(\d+)-(\d+)-(\d+).data$/',$fileinfo->getFilename(),$match);
            $table = $match[1];
            $pdo->query("CREATE TABLE IF NOT EXISTS `$table` (dtlog INT, glot INT);");
            $stmt = $pdo->prepare('INSERT INTO `'.$table.'` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) on duplicate key update glot=:glot');
            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);
                    $stmt->execute();
                    echo 'insertion de la ligne '.$i.'<br />';
                    $i++;
                    //rename("./PENDANT/$fileinfo", "./APRES/$fileinfo");
                }
            }
        }
    }
} catch (Exception $e) {
    echo $e->getMessage() . '<br />' . $e->getTraceAsString();
}
J'ai viré la première colonne "poste" et réussi à créer la table si elle n'existe pas par :
$pdo->query("CREATE TABLE IF NOT EXISTS `$table` (dtlog INT, glot INT);");
Pour mettre à jour automatiquement la valeur si déjà présente dans la table, je sais qu'il faut utiliser INSERT INTO ... ON DUPLICATE KEY UPDATE mais je fais une erreur avec le dernier paramètre glot=:glot, est ce parce que je n'ai pas défini de PRIMARY KEY ? :
$stmt = $pdo->prepare('INSERT INTO `'.$table.'` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) on duplicate key update glot=:glot');
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?=?' at line 1
#0 C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\testparserdata5.php(19): PDO->prepare('INSERT INTO `34...') #1 {main}
Pour déplacer le fichier, je bloque également en ce qui concerne l'utilisation du fichier déplacé. Avec le
rename("./AVANT/$fileinfo", "./PENDANT/$fileinfo");
avant traitement et le
rename("./PENDANT/$fileinfo", "./APRES/$fileinfo");
après traitement.
Warning: file(C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\AVANT\fic34154001-2013-10-03.data): failed to open stream: No such file or directory in C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\testparserdata5.php on line 15
Merci!!!

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

08 oct. 2013, 22:37

oui si dtlog n'est pas une colonne unique (unique ou pk) effectivement ce que tu as fait ne peux fonctionner ;)

ensuite le message indique que le fichier n'existe pas, j'ai tendance à croire php dans ce cas ;)

pourquoi ?

parce que le nom du fichier c'est $fileinfo->getPathname() et pas fileinfo, regarde la doc ;)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 103 Messages

09 oct. 2013, 13:30

Navré, j'ai beau essayer toutes les combinaisons, quelque chose m'échappe pour les rename des lignes 13 et 30 (d'ailleurs ce code ne fonctionne absolument pas, rien n'est déplacé à contrario de l'utilisation de $fileinfo seul)!
Pour moi ça devrait bien etre rename("./AVANT/$fileinfo", "./PENDANT/$fileinfo"); et non pas avec $fileinfo->getPathname().
<?php
try {
    // connexion
    $pdo = new PDO('mysql:host=localhost;dbname=labase', 'PDO', '290585');
    $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
    $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);

    $dir = new DirectoryIterator(dirname(__FILE__) . '\AVANT');  
    foreach ($dir as $fileinfo) { 
        if (!$fileinfo->isDot() && $fileinfo->isFile() && $fileinfo->getExtension() == 'data') {
            rename("./AVANT/$fileinfo->getPathname()", "./PENDANT/$fileinfo->getPathname()");
            echo 'parse du fichier : '.$fileinfo->getFilename().'<br />';
            $tabFile = file($fileinfo->getPathname());
            preg_match('/^fic(\d+)-(\d+)-(\d+)-(\d+).data$/',$fileinfo->getFilename(),$match);
            $table = $match[1];
            $pdo->query("CREATE TABLE IF NOT EXISTS `$table` (dtlog  INT PRIMARY KEY, glot INT);");
            $stmt = $pdo->prepare('INSERT INTO `'.$table.'` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE glot = VALUES(glot)');
            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);
                    $stmt->execute();
                    echo 'insertion de la ligne '.$i.'<br />';
                    $i++;
                    rename("./PENDANT/$fileinfo->getPathname()", "./APRES/$fileinfo->getPathname()");
                }
            }
        }
    }
} catch (Exception $e) {
    echo $e->getMessage() . '<br />' . $e->getTraceAsString();
}
Notice: Undefined property: DirectoryIterator::$getPathname in C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\testparserdata5.php on line 13

Notice: Undefined property: DirectoryIterator::$getPathname in C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\testparserdata5.php on line 13

Warning: rename(./AVANT/(),./PENDANT/()): in C:\Program Files (x86)\EasyPHP-DevServer-13.1VC11\data\localweb\scripts\testparserdata5.php on line 13
parse du fichier : fic34154001-2013-10-03.data
insertion de la ligne 0

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

10 oct. 2013, 21:29

aller avec des neurones un peu plus en forme je regarde la doc et je vois la description sommaire des méthodes de l'objet DirectoryIterator
DirectoryIterator::getBasename() - Lit le nom de dossier de l'élément DirectoryIterator
DirectoryIterator::getFilename() - Retourne le nom de l'entrée courante du dossier
DirectoryIterator::getPath() - Retourne le chemin du dossier
pathinfo() - Retourne des informations sur un chemin système
sachant le nom du fichier courant est obtenu avec $fileinfo->getFilename() et que le chemin complet est obtenue avec $fileinfo->getPath() (sans / final) je dirais donc que le déplacement initial est
<?php
rename($originalDir . $fileinfo->getFilename(), $tmpFolder . $fileinfo->getFilename());
le final
<?php
rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());
le tous dans le code un peu plus clair
<?php
try {
    // connexion
    $pdo = new PDO('mysql:host=localhost;dbname=josse34', 'josse34', 'josse34');
    $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
    $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);

    $tmpFolder = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
    $finalFolder = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'final' . DIRECTORY_SEPARATOR;
    $originalDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'avant' . DIRECTORY_SEPARATOR;

    $dir = new DirectoryIterator($originalDir);
    foreach ($dir as $fileinfo) {
        if (!$fileinfo->isDot() && $fileinfo->isFile() && $fileinfo->getExtension() == 'data') {
            echo 'parse du fichier : ' . $fileinfo->getFilename() . '<br />';

            rename($originalDir . $fileinfo->getFilename(), $tmpFolder . $fileinfo->getFilename());

            $tabFile = file($tmpFile);
            preg_match('/^fic(\d+)-(\d+)-(\d+)-(\d+).data$/', $fileinfo->getFilename(), $match);
            $table = $match[1];
            $stmt = $pdo->prepare('INSERT INTO `' . $table . '` (poste,dtlog, glot) VALUES (:poste,str_to_date(:dt,\'%Y%m%d\'),:glot)');
            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':poste', $csv[0], PDO::PARAM_INT);
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);
                    $stmt->execute();
                    echo 'insertion de la ligne ' . $i . '<br />';
                    $i++;
                }
            }
        }
        rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());
    }
} catch (Exception $e) {
    echo $e->getMessage() . '<br />' . $e->getTraceAsString();
}
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 103 Messages

11 oct. 2013, 11:02

Alleluia !!!!!!!!!!
Merci Moogli!!!!!
Tout fonctionne à merveille!!!!!
=D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D> =D>
Je teste sur mon serveur et indique résolu si tout roule