mercredi 13 novembre 2013

Appends concurrents

Lors de la création d'un fichier CSV, je faisais "bêtement" (code simplifié) :
$txt = file_exists('fichier.csv') ? '' : "colonne1;colonn2";
$txt .= "\n" . implode(';', $data);
file_put_contents('fichier.csv', $txt, FILE_APPEND);

Tout allait bien jusqu'au moment où j'ai lancé ce script depuis plusieurs processus en parallèle.


En effet, entre le test de la présence du fichier et l'écriture, on pouvait avoir un autre script faisant la même chose. Du coup, dans le fichier CSV, on se retrouvait avec l'entête sur la 3ième ligne (j'ai même réussis à en avoir 3 en même temps).

Du coup, voici comment je fais mes appends désormais :

$f = fopen('fichier.csv', 'a');
flock($f, LOCK_EX);
$stats = fstats($f);
if ($stats['size'] === 0) {
    fputs($f, 'colonne1;colonn2');
}
fputs($f, "\n" . implode(';', $data));
fclose($f);
Ainsi, le fichier étant bloqué en écriture, on peut prendre son temps pour tester sa taille est ajouter l'entête si nécessaire.

Aucun commentaire:

Enregistrer un commentaire