Lire et écrire dans un fichier csv

Les fichiers csv sont assez commun lorsque l'on parle d'import ou d'export de données. Et PHP facilite la création et la lecture de ces fichiers grâce à deux méthodes : fputcsv et fgetcsv.

Ecrire un fichier csv

Pour écrire un fichier csv, nous allons utiliser fputcsv.

$data = [
    [1, 'John', 'Doe'],
    [2, 'Jane', 'Doe'],
    [3, 'Baby', 'Doe'],
];

$fp = fopen('export.csv', 'w');
foreach ($data as $row) {
    fputcsv($fp, $row);
}
fclose($fp);

Contenu du fichier export.csv :

1,John,Doe
2,Jane,Doe
3,Baby,Doe

Si vous préférez que les champs soient séparés par des ;, alors il faut l'indiquer en 3ᵉ paramètre :

fputcsv($fp, $row, ';');
1;John;Doe
2;Jane;Doe
3;Baby;Doe

Mais comment faire si vos données contiennent des ; ou des , ?

$data = [
    [1, 'John', 'Doe', '1 avenue du soleil, FRANCE'],
    [2, 'Jane', 'Doe', '1 avenue de la pluie, FRANCE'],
    [3, 'Baby', 'Doe', '2 bras de papa'],
];

PHP va entourer automatiquement le champ contenant la virgule avec des ".

1,John,Doe,"1 avenue du soleil, FRANCE"
2,Jane,Doe,"1 avenue de la pluie, FRANCE"
3,Baby,Doe,"2 bras de papa"

Mais si ce caractère ne vous convient pas, vous pouvez spécifier celui de votre choix lors de l'appel à fputcsv :

fputcsv($fp, $row, ',', '*');
1,John,Doe,*1 avenue du soleil, FRANCE*
2,Jane,Doe,*1 avenue de la pluie, FRANCE*
3,Baby,Doe,*2 bras de papa*

Et pour lire les csv ?

On peut utiliser la fonction fgetcsv :

$data = [];
$fp = fopen('import.csv', 'r');
while (($row = fgetcsv($fp)) !== false) {
    $data[] = $row;
}
fclose($fp);

fgetcsv prend en deuxième paramètre la longueur de la ligne à récupérer à chaque fois. Depuis PHP 8.0, ce paramètre n'est plus obligatoire et donc, si non spécifié, la ligne complète est récupérée à chaque fois (avant il fallait mettre 0 si on ne voulait pas mettre de limite).

Mais pourquoi spécifier une longueur de ligne ? D'après la documentation, le fait d'indiquer la longueur des données à récupérer permet d'accélérer un peu le traitement (je ne l'ai pas spécialement vérifié pendant mes tests, donc on va faire confiance à la documentation).

On peut aussi lors de la lecture, spécifier le séparateur de champ et le caractère d'encadrement de la même manière qu'avec fputcsv :

$row = fgetcsv($fp, null, ';', '*');

Cet article t'a plu ? Si oui, je te propose de t'inscrire à ma dev letter pour recevoir régulièrement dans ta boîte mail mes conseils, mes nouveaux articles, des vidéos à voir, des outils à découvrir et encore bien d’autres choses.

Je m'inscris