189 votes

Comment analyser un fichier CSV en PHP ?

Supposons que j'ai un .csv avec le contenu suivant :

 "text, with commas","another text",123,"text",5; 
 "some    without commas","another text",123,"text";
 "some text with  commas or no",,123,"text"; 

Comment puis-je analyser le contenu en PHP ?

0 votes

En fait, vous demandez s'il existe une meilleure façon de traiter le parsing CSV que l'approche classique des fonctions globales. Je dirais qu'il faut reformuler la question, car cela ne ressemble pas vraiment à un problème d'analyse d'un CSV.

1 votes

@quickshiftin désolé pour ça

0 votes

C'est bon, je dis juste... Si tu veux un cours celui-ci est OK (je l'ai un peu modifié dans mon travail tho )

250voto

thenetimp Points 2300

Utilisez simplement la fonction d'analyse syntaxique d'un fichier CSV.

http://php.net/manual/en/function.fgetcsv.php

$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $num = count($data);
    echo "<p> $num fields in line $row: <br /></p>\n";
    $row++;
    for ($c=0; $c < $num; $c++) {
        echo $data[$c] . "<br />\n";
    }
  }
  fclose($handle);
}

39 votes

Il faut noter que cette fonction ne traite pas correctement les guillemets dans le CSV. Plus précisément, elle ne peut pas traiter cet exemple tel que trouvé dans wikipedia : fr.wikipedia.org/wiki/Comma-separated_values#Example il y a eu un bug ouvert, mais il a été fermé car "ne sera pas corrigé". bugs.php.net/bug.php?id=50686

3 votes

Ne fonctionne pas correctement sur les colonnes dont le contenu comporte également des sauts de ligne

167voto

Aldekein Points 408

Une réponse un peu plus courte puisque PHP >= 5.3.0 :

    $csvFile = file('../somefile.csv');
    $data = [];
    foreach ($csvFile as $line) {
        $data[] = str_getcsv($line);
    }

36 votes

Notez que cela ne fonctionne pas si vous avez des retours à la ligne dans les valeurs réelles (pas les délimiteurs de ligne à la fin de chaque ligne csv), parce que la fonction file se sépare sur les nouvelles lignes et ne tient pas compte des guillemets que le CSV utilise pour contenir les valeurs des champs.

0 votes

@JordanLev alors que recommandez-vous ?

6 votes

@Julix utilise la réponse acceptée . Cette version abrégée est intéressante si vous savez que les données importées ne comporteront jamais de sauts de ligne à l'intérieur d'une même valeur, mais sinon la solution plus robuste vaut les lignes de code supplémentaires.

156voto

Maxim Kovalevsky Points 1376

Un outil pratique pour analyser un fichier CSV dans un tableau.

$csv = array_map('str_getcsv', file('data.csv'));

30 votes

Notez que cela ne fonctionne pas si vous avez des retours à la ligne dans les valeurs réelles (pas les délimiteurs de ligne à la fin de chaque ligne csv), parce que la fonction file se sépare sur les nouvelles lignes et ne connaît pas les guillemets que CSV utilise pour contenir les valeurs des champs.

5 votes

Comment utiliser un délimiteur différent ? ( ; au lieu de , )

13 votes

Utilisez ce qui suit pour résoudre le problème des nouvelles lignes : array_map('str_getcsv', file('data.csv' , FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)) ;

22voto

quartarian Points 509

Je viens de découvrir un moyen pratique d'obtenir un index pendant l'analyse syntaxique. J'ai été époustouflé.

$handle = fopen("test.csv", "r");
for ($i = 0; $row = fgetcsv($handle ); ++$i) {
    // Do something will $row array
}
fclose($handle);

Source : lien

1 votes

Notre serveur est équipé de PHP 5.2.9 et je ne peux pas accéder à str_getcsv à cause de cela. fgetcsv, par contre, date de PHP 4, donc c'est utile. Merci.

0 votes

Je me demande juste pourquoi une boucle for a été utilisée au lieu d'une boucle while ?

2 votes

@valerie J'ai presque toujours besoin d'un index lors de l'analyse des CSV. La boucle for fournit l'index sans une déclaration et un incrémenteur séparés.

9voto

ackuser Points 1913

J'adore ça.

$data = str_getcsv($CsvString, "\n"); //parse the rows
foreach ($data as &$row) {
    $row = str_getcsv($row, "; or , or whatever you want"); //parse the items in rows 
    $this->debug($row);
}

dans mon cas, je vais obtenir un csv par le biais de services web, donc de cette façon je n'ai pas besoin de créer le fichier. Mais si vous avez besoin de parser avec un fichier, il est seulement nécessaire de passer comme string

0 votes

Cela n'a pas fonctionné correctement pour moi. Par exemple, ceci : aaa,bbb,"ccc\nddd",eee a été analysé en deux lignes (au lieu de la ligne souhaitée) au lieu d'une seule. Il semble que " n'est pas reconnu comme une clôture lorsqu'il apparaît à l'intérieur du champ (plutôt qu'à son début ou à sa fin). Ainsi, $data = str_getcsv(..) peut être remplacé par $data = explode(..) ce qui, j'imagine, est plus efficace, et transmet mieux l'intention...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X