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, ';', '*');

Vous aimeriez progresser en PHP ? Mais vous ne savez pas comment vous y prendre ?

S'entraîner pour progresser en PHP

Mon programme "S'entraîner pour progresser en PHP" est disponible. Il vous permettra de recevoir chaque semaine un kata de code directement dans votre boîte mail, ainsi que des aides à la réalisation, des vidéos explicatives et des défis supplémentaires.

Reçois dès maintenant un kata gratuit en cliquant sur le bouton ci-dessous.