So erstellen Sie ein Array aus einer CSV-Datei mit PHP und der Funktion fgetcsv


106

Kann jemand freundlicherweise einen Code zum Erstellen eines Arrays aus einer CSV-Datei mit fgetcsv bereitstellen?

Ich habe den folgenden Code verwendet, um ein Array aus einer einfachen CSV-Datei zu erstellen, aber es funktioniert nicht richtig, wenn eines meiner Felder mehrere Kommas enthält - z. B. Adressen.

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

foreach($lines as $data)
{
list($name[],$address[],$status[])
= explode(',',$data);
}

* Außerdem wird str_getcsv von meinem Hosting-Service nicht unterstützt.

Der obige Code funktioniert nicht mit dem folgenden CSV-Dateibeispiel. Die erste Spalte ist der Name, die zweite Spalte ist die Adresse, die dritte Spalte ist der Familienstand.

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

2
Festgefahren mit PHP 5.2 wie? Ich fühle für Sie, ich bin mit meinem Hosting-Anbieter im selben Boot.
Adam F

Sie können diesen Helfer verwenden: github.com/rap2hpoutre/csv-to-associative-array
rap-2-h

Antworten:


179

Wie Sie in Ihrem Titel gesagt haben, ist fgetcsv der richtige Weg. Es ist verdammt einfach zu bedienen.

$file = fopen('myCSVFile.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
  //$line is an array of the csv elements
  print_r($line);
}
fclose($file);

Sie sollten dort weitere Fehlerprüfungen durchführen, falls dies fopen()fehlschlägt. Dies funktioniert jedoch, um eine CSV-Datei Zeile für Zeile zu lesen und die Zeile in ein Array zu analysieren.


Vielen Dank, Dave, aber Ihr Beispiel enthält nur ein Array mit den folgenden drei Positionen: $ line [0], $ line [1] und $ line [2]. Das ist in Ordnung für die erste Zeile, aber ich muss separate Positionen für die 2., 3., 4. usw. Zeile erstellen. Auf diese Weise kann ich die Zeilen separat bearbeiten. Hoffe das macht Sinn
Thomas

7
@ Thomas Wenn Sie eine Reihe von Namen, Adressen und Status benötigen, können Sie einfach das tun, was Sie oben tun: list($names[], $addresses[], $statuses[]) = $line;
Dave DeLong

Nochmals vielen Dank Dave! Das hat mich gestolpert.
Thomas

Ich habe eine Frage zu dieser Funktion. Wenn in einem der CSV-Felder eine neue Zeile enthalten ist, wird die Zeile derzeit als einzelner Datensatz analysiert. Oder werden stattdessen zwei (verstümmelte) Datensätze zurückgegeben?
Alix Axel

warum müssen wir am ende schließen?
wütend Kiwi

55

Ich denke, die Syntax str_getcsv () ist viel sauberer, es erfordert auch nicht, dass die CSV im Dateisystem gespeichert wird.

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

echo '<pre>';
print_r($csv);
echo '</pre>';

Oder für eine zeilenweise Lösung:

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

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

echo '<pre>';
print_r($csv);
echo '</pre>';

Oder für eine zeilenweise Lösung ohne str_getcsv ():

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

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

fclose($file);

echo '<pre>';
print_r($csv);
echo '</pre>';

2
Zu Ihrer Information: str_getcsv () ist nur ab PHP 5.3.0 verfügbar. Das Projekt, an dem ich arbeite, hat es von 1 Version DOH! (Wir verwenden 5.2.9 atm).
Jim Ford

Das ist ausgezeichnet, es sei denn, Sie haben Speicherbeschränkungen. Die fgetcsv-Lösung funktioniert mit jeder Hardwarekonfiguration.
Sp4cecat

4
IN ACHT NEHMEN! Es gibt einen Fehler mit str_getcsv, der dazu führt, dass Zeilenenden ignoriert werden: bugs.php.net/bug.php?id=55763&edit=1
RJD22

Beachten Sie, dass Sie Folgendes tun können: while (! Feof ($ file)) {$ csv [] = fgetcsv ($ file); } statt while (($ result = fgetcsv ($ file))! == false) {$ csv [] = $ result; }
David G

23

Ich habe eine Funktion erstellt, die eine CSV-Zeichenfolge in ein Array konvertiert. Die Funktion kann Sonderzeichen umgehen und funktioniert mit oder ohne Gehäusezeichen.

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

Ich habe es mit Ihrem CSV-Beispiel versucht und es funktioniert wie erwartet!

function csvstring_to_array($string, $separatorChar = ',', $enclosureChar = '"', $newlineChar = "\n") {
    // @author: 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){
                    // escaped char
                    $addChar=$char;
                    $i++; // dont check next char
                }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) { // save last field
        $array[$rowIndex][$columnIndex] = $fieldValue;
    }
    return $array;
}

16
$arrayFromCSV =  array_map('str_getcsv', file('/path/to/file.csv'));

1
Der Einfachheit halber Daumen hoch
kudlohlavec

14

Alte Frage, aber immer noch relevant für PHP 5.2-Benutzer. str_getcsv ist ab PHP 5.3 verfügbar. Ich habe eine kleine Funktion geschrieben, die mit fgetcsv selbst funktioniert.

Unten ist meine Funktion von 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: Invalid number of columns at line " . ($rowcount + 2) . " (row " . ($rowcount + 1) . "). Expected=$header_colcount Got=$row_colcount");
                return null;
            }
            $rowcount++;
        }
        //echo "Totally $rowcount rows found\n";
        fclose($handle);
    }
    else {
        error_log("csvreader: Could not read CSV \"$csvfile\"");
        return null;
    }
    return $csv;
}

Kehrt zurück

Beginnen Sie mit dem Lesen von CSV

Array
(
    [0] => Array
        (
            [vid] => 
            [agency] => 
            [division] => Division
            [country] => 
            [station] => Duty Station
            [unit] => Unit / Department
            [grade] => 
            [funding] => Fund Code
            [number] => Country Office Position Number
            [wnumber] => Wings Position Number
            [title] => Position Title
            [tor] => Tor Text
            [tor_file] => 
            [status] => 
            [datetime] => Entry on Wings
            [laction] => 
            [supervisor] => Supervisor Index Number
            [asupervisor] => Alternative Supervisor Index
            [author] => 
            [category] => 
            [parent] => Reporting to Which Position Number
            [vacant] => Status (Vacant / Filled)
            [index] => Index Number
        )

    [1] => Array
        (
            [vid] => 
            [agency] => WFP
            [division] => KEN Kenya, The Republic Of
            [country] => 
            [station] => Nairobi
            [unit] => Human Resources Officer P4
            [grade] => P-4
            [funding] => 5000001
            [number] => 22018154
            [wnumber] => 
            [title] => Human Resources Officer P4
            [tor] => 
            [tor_file] => 
            [status] => 
            [datetime] => 
            [laction] => 
            [supervisor] => 
            [asupervisor] => 
            [author] => 
            [category] => Professional
            [parent] => 
            [vacant] => 
            [index] => xxxxx
        )
) 

Übrigens können Sie fgetcsv optionale Parameter hinzufügen, um Trennzeichen, Gehäusezeichen usw. zu ändern.
Manu Manjunath

4

Versuche dies..

function getdata($csvFile){
    $file_handle = fopen($csvFile, 'r');
    while (!feof($file_handle) ) {
        $line_of_text[] = fgetcsv($file_handle, 1024);
    }
    fclose($file_handle);
    return $line_of_text;
}


// Set path to CSV file
$csvFile = 'test.csv';

$csv = getdata($csvFile);
echo '<pre>';
print_r($csv);
echo '</pre>';

Array
(
    [0] => Array
        (
            [0] => Project
            [1] => Date
            [2] => User
            [3] => Activity
            [4] => Issue
            [5] => Comment
            [6] => Hours
        )

    [1] => Array
        (
            [0] => test
            [1] => 04/30/2015
            [2] => test
            [3] => test
            [4] => test
            [5] => 
            [6] => 6.00
        ));

3

Diese Funktion gibt ein Array mit Header-Werten als Array-Schlüssel zurück.

function csv_to_array($file_name) {
        $data =  $header = array();
        $i = 0;
        $file = fopen($file_name, 'r');
        while (($line = fgetcsv($file)) !== FALSE) {
            if( $i==0 ) {
                $header = $line;
            } else {
                $data[] = $line;        
            }
            $i++;
        }
        fclose($file);
        foreach ($data as $key => $_value) {
            $new_item = array();
            foreach ($_value as $key => $value) {
                $new_item[ $header[$key] ] =$value;
            }
            $_data[] = $new_item;
        }
        return $_data;
    }

3

Um ein Array mit den richtigen Schlüsseln zu erhalten, können Sie Folgendes versuchen:

// Open file
$file = fopen($file_path, 'r');

// Headers
$headers = fgetcsv($file);

// Rows
$data = [];
while (($row = fgetcsv($file)) !== false)
{
    $item = [];
    foreach ($row as $key => $value)
        $item[$headers[$key]] = $value ?: null;
    $data[] = $item;
}

// Close file
fclose($file);

1

Bitte finden Sie unten einen Link zur Funktion von @knagode, der um einen Parameter zum Überspringen von Zeilen erweitert wurde. https://gist.github.com/gabrieljenik/47fc38ae47d99868d5b3#file-csv_to_array

<?php
    /**
     * Convert a CSV string into an array.
     * 
     * @param $string
     * @param $separatorChar
     * @param $enclosureChar
     * @param $newlineChar
     * @param $skip_rows
     * @return array
     */
    public static function csvstring_to_array($string, $skip_rows = 0, $separatorChar = ';', $enclosureChar = '"', $newlineChar = "\n") {
        // @author: Klemen Nagode 
        // @source: http://stackoverflow.com/questions/1269562/how-to-create-an-array-from-a-csv-file-using-php-and-the-fgetcsv-function
        $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){
                        // escaped char
                        $addChar=$char;
                        $i++; // dont check next char
                    }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) { // save last field
            $array[$rowIndex][$columnIndex] = $fieldValue;
        }


        /**
         * Skip rows. 
         * Returning empty array if being told to skip all rows in the array.
         */ 
        if ($skip_rows > 0) {
            if (count($array) == $skip_rows)
                $array = array();
            elseif (count($array) > $skip_rows)
                $array = array_slice($array, $skip_rows);           

        }

        return $array;
    }

1
Bitte erläutern Sie im Stackoverflow mehr als nur einen Link.
Paul Lo

1

Ich habe mir diesen ziemlich einfachen Code ausgedacht. Ich denke, es könnte für jeden nützlich sein.

$link = "link to the CSV here"
$fp = fopen($link, 'r');

while(($line = fgetcsv($fp)) !== FALSE) {
    foreach($line as $key => $value) {
        echo $key . " - " . $value . "<br>";
    }
}


fclose($fp);

1

Wenn Sie möchten, dass sich jede Zeile in einem Array und jede Zelle in der Zeile im Array befindet:

$file = fopen('csvFile.csv', 'r');              // Open the file                     
while (($line = fgetcsv($file)) !== FALSE) {    // Read one line
    $array[] =$line;                            // Add the line in the main array
}
echo '<pre>';
print_r($array);   //print it out
echo '</pre>'; 
fclose($file);

0

Versuchen Sie diesen Code:

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

1
Was ist der Grund, genau den gleichen Antwort-Fragesteller zu posten?
Pinepain

0
 function csvToArray($path)
{
    try{
        $csv = fopen($path, 'r');
        $rows = [];
        $header = [];
        $index = 0;
        while (($line = fgetcsv($csv)) !== FALSE) {
            if ($index == 0) {
                $header = $line;
                $index = 1;
            } else {
                $row = [];
                for ($i = 0; $i < count($header); $i++) {
                    $row[$header[$i]] = $line[$i];
                }
                array_push($rows, $row);
            }
        }
        return $rows;
    }catch (Exception $exception){
        return false;
    }
}

0
convertToArray(file_get_content($filename));

function convertToArray(string $content): array
{
   $data = str_getcsv($content,"\n");
   array_walk($data, function(&$a) use ($data) {
       $a = str_getcsv($a);
   });

   return $data;
}

was ist die Frage?
SpongePablo

Siehe " Erklären vollständig codebasierter Antworten ". Dies mag zwar technisch korrekt sein, erklärt jedoch nicht, warum es das Problem löst oder die ausgewählte Antwort sein sollte. Wir sollten zusätzlich aufklären, um das Problem zu lösen.
Der Blechmann
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.