149 votes

Comment créer un tableau à partir d'un fichier CSV en utilisant PHP et la fonction fgetcsv

Est-ce que quelqu'un pourrait gentiment fournir un code pour créer un tableau à partir d'un fichier CSV en utilisant fgetcsv?

J'ai utilisé le code suivant pour créer un tableau à partir d'un fichier CSV simple, mais ça ne fonctionne pas correctement quand l'un de mes champs a plusieurs virgules - comme les adresses.

$lignes = file('CSV Address.csv');

foreach($lignes as $data)
{
list($nom[], $adresse[], $statut[])
= explode(',',$data);
}

*De plus, str_getcsv n'est pas pris en charge par mon service d'hébergement.

Le code ci-dessus ne fonctionne pas avec l'exemple de fichier CSV suivant. La première colonne est le nom, la deuxième colonne est l'adresse, la troisième colonne est l'état marital.

Scott L. Aranda,"123 Main Street, Bethesda, Maryland 20816",Célibataire
Todd D. Smith,"987 Elm Street, Alexandria, Virginia 22301",Célibataire
Edward M. Grass,"123 Main Street, Bethesda, Maryland 20816",Marié
Aaron G. Frantz,"987 Elm Street, Alexandria, Virginia 22301",Marié
Ryan V. Turner,"123 Main Street, Bethesda, Maryland 20816",Célibataire

3 votes

Resté avec PHP 5.2, hein? Je compatis, je suis dans le même bateau avec mon fournisseur d'hébergement.

1 votes

Vous pouvez utiliser ce helper: github.com/rap2hpoutre/csv-to-associative-array

231voto

Dave DeLong Points 156978

Comme vous l'avez dit dans votre titre, fgetcsv est la méthode à suivre. C'est assez facile à utiliser.

$file = fopen('myCSVFile.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
  //$line est un tableau des éléments du csv
  print_r($line);
}
fclose($file);

Vous voudrez ajouter plus de vérifications d'erreur au cas où fopen() échoue, mais cela fonctionne pour lire un fichier CSV ligne par ligne et analyser la ligne en un tableau.

0 votes

Merci Dave mais votre exemple ne fournit qu'un tableau avec les trois positions suivantes : $line[0], $line[1] et $line[2]. C'est bien pour la première ligne, mais j'ai besoin de créer des positions séparées pour les lignes 2, 3, 4, etc. De cette façon, je peux manipuler les lignes séparément. J'espère que c'est clair

10 votes

@Thomas Si vous avez besoin d'un tableau de noms, adresses et statuts, vous pouvez simplement faire ce que vous faites ci-dessus : list($names[], $addresses[], $statuses[]) = $line;

0 votes

J'ai une question sur cette fonction, si l'un des champs CSV a une nouvelle ligne, le traitera-t-il actuellement comme un seul enregistrement ? Ou renverra-t-il deux enregistrements (mélangés) à la place ?

79voto

Alix Axel Points 63455

Je pense que la syntaxe de str_getcsv() est beaucoup plus propre, et ne nécessite pas que le CSV soit stocké dans le système de fichiers.

$csv = str_getcsv(file_get_contents('myCSVFile.csv'));

echo '';
print_r($csv);
echo '';

Ou pour une solution ligne par ligne :

$csv = array();
$lines = file('myCSVFile.csv', FILE_IGNORE_NEW_LINES);

foreach ($lines as $key => $value)
{
    $csv[$key] = str_getcsv($value);
}

echo '';
print_r($csv);
echo '';

Ou pour une solution ligne par ligne sans str_getcsv() :

$csv = array();
$file = fopen('myCSVFile.csv', 'r');

while (($result = fgetcsv($file)) !== false)
{
    $csv[] = $result;
}

fclose($file);

echo '';
print_r($csv);
echo '';

3 votes

FYI : str_getcsv () est disponible uniquement à partir de PHP 5.3.0. Le projet sur lequel je travaille l'a manqué d'une version DOH! (nous utilisons la version 5.2.9 pour le moment).

0 votes

C'est excellent, à moins que vous n'ayez des restrictions de mémoire. La solution fgetcsv fonctionne avec n'importe quelle configuration matérielle.

6 votes

FAITES ATTENTION ! il y a un bug avec str_getcsv qui le fait ignorer les sauts de ligne : bugs.php.net/bug.php?id=55763&edit=1

29voto

knagode Points 1176

J'ai créé une fonction qui convertira une chaîne CSV en un tableau. La fonction sait comment échapper les caractères spéciaux et fonctionne avec ou sans caractères d'encadrement.

$dataArray = csvstring_to_array( file_get_contents('Address.csv'));

Je l'ai essayé avec votre exemple CSV et cela fonctionne comme prévu!

function csvstring_to_array($string, $separatorChar = ',', $enclosureChar = '"', $newlineChar = "\n") {
    // @auteur: Klemen Nagode
    $array = array();
    $size = strlen($string);
    $columnIndex = 0;
    $rowIndex = 0;
    $fieldValue="";
    $isEnclosured = false;
    for($i=0; $i<$size;$i++) {

        $char = $string{$i};
        $addChar = "";

        if($isEnclosured) {
            if($char==$enclosureChar) {

                if($i+1<$size && $string{$i+1}==$enclosureChar){
                    // char échappé
                    $addChar=$char;
                    $i++; // ne pas vérifier le caractère suivant
                }else{
                    $isEnclosured = false;
                }
            }else {
                $addChar=$char;
            }
        }else {
            if($char==$enclosureChar) {
                $isEnclosured = true;
            }else {

                if($char==$separatorChar) {

                    $array[$rowIndex][$columnIndex] = $fieldValue;
                    $fieldValue="";

                    $columnIndex++;
                }elseif($char==$newlineChar) {
                    echo $char;
                    $array[$rowIndex][$columnIndex] = $fieldValue;
                    $fieldValue="";
                    $columnIndex=0;
                    $rowIndex++;
                }else {
                    $addChar=$char;
                }
            }
        }
        if($addChar!=""){
            $fieldValue.=$addChar;

        }
    }

    if($fieldValue) { // sauvegarder le dernier champ
        $array[$rowIndex][$columnIndex] = $fieldValue;
    }
    return $array;
}

21voto

Manu Points 1725

Ancienne question, mais toujours pertinente pour les utilisateurs de PHP 5.2. str_getcsv est disponible à partir de PHP 5.3. J'ai écrit une petite fonction qui fonctionne avec fgetcsv elle-même.

Voici ma fonction depuis https://gist.github.com/4152628:

function parse_csv_file($csvfile) {
    $csv = Array();
    $rowcount = 0;
    if (($handle = fopen($csvfile, "r")) !== FALSE) {
        $max_line_length = defined('MAX_LINE_LENGTH') ? MAX_LINE_LENGTH : 10000;
        $header = fgetcsv($handle, $max_line_length);
        $header_colcount = count($header);
        while (($row = fgetcsv($handle, $max_line_length)) !== FALSE) {
            $row_colcount = count($row);
            if ($row_colcount == $header_colcount) {
                $entry = array_combine($header, $row);
                $csv[] = $entry;
            }
            else {
                error_log("csvreader: Nombre de colonnes invalide à la ligne " . ($rowcount + 2) . " (ligne " . ($rowcount + 1) . "). Attendu=$header_colcount Reçu=$row_colcount");
                return null;
            }
            $rowcount++;
        }
        //echo "Au total, $rowcount lignes trouvées\n";
        fclose($handle);
    }
    else {
        error_log("csvreader: Impossible de lire le CSV \"$csvfile\"");
        return null;
    }
    return $csv;
}

Renvoie

Commencez la lecture du CSV

Array
(
    [0] => Array
        (
            [vid] => 
            [agency] => 
            [division] => Division
            [country] => 
            [station] => Poste de service
            [unit] => Unité / Département
            [grade] => 
            [funding] => Code de financement
            [number] => Numéro de poste de bureau de pays
            [wnumber] => Numéro de poste Wings
            [title] => Intitulé du poste
            [tor] => Texte de Tor
            [tor_file] => 
            [status] => 
            [datetime] => Entrée sur Wings
            [laction] => 
            [supervisor] => Numéro d'index du superviseur
            [asupervisor] => Numéro d'index de superviseur alternatif
            [author] => 
            [category] => 
            [parent] => Rendre compte à quel numéro de poste
            [vacant] => Statut (Vacant / Occupé)
            [index] => Numéro d'index
        )

    [1] => Array
        (
            [vid] => 
            [agency] => PAM
            [division] => KEN Kenya, La République de
            [country] => 
            [station] => Nairobi
            [unit] => Officier des ressources humaines P4
            [grade] => P-4
            [funding] => 5000001
            [number] => 22018154
            [wnumber] => 
            [title] => Officier des ressources humaines P4
            [tor] => 
            [tor_file] => 
            [status] => 
            [datetime] => 
            [laction] => 
            [supervisor] => 
            [asupervisor] => 
            [author] => 
            [category] => Professionnel
            [parent] => 
            [vacant] => 
            [index] => xxxxx
        )
)

0 votes

Au fait, vous pouvez ajouter des paramètres facultatifs à fgetcsv pour changer le délimiteur, le caractère d'enclosure, etc.

-1voto

Indrajeet Singh Points 604

Essayez ce code :

function readCsv($file)
{
    if (($handle = fopen($file, 'r')) !== FALSE) {
        while (($lineArray = fgetcsv($handle, 4000)) !== FALSE) {
            print_r(lineArray);
        }
        fclose($handle);
    }
}

2 votes

Quelle est la raison de publier exactement la même réponse que celle appliquée par le demandeur?

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