So analysieren Sie eine CSV-Datei mit PHP [duplicate]

Lesezeit: 8 Minuten

So analysieren Sie eine CSV Datei mit PHP duplicate
Schmied

Angenommen, ich habe eine .csv Datei mit folgendem Inhalt:

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

Wie kann ich den Inhalt über PHP parsen?

  • Sie fragen sich im Grunde, ob es eine bessere OOP-Methode für den Umgang mit CSV-Parsing gibt als den globalen Aktienfunktionsansatz. Ich würde sagen, die Frage umformulieren, da dies nicht wirklich nach einem Problem beim Analysieren einer CSV klingt.

    – Schnellschaltung

    4. Februar 2012 um 7:33 Uhr

  • @quickshiftin tut mir leid

    – Schmied

    4. Februar 2012 um 7:36 Uhr

  • Es ist in Ordnung, ich sage nur… Wenn du einen Unterricht willst Dieses hier ist in Ordnung (ich habe es in meiner Arbeit ein wenig angepasst, aber ..)

    – Schnellschaltung

    4. Februar 2012 um 7:43 Uhr

1646633049 427 So analysieren Sie eine CSV Datei mit PHP duplicate
thenetimp

Verwenden Sie einfach die Funktion zum Parsen einer CSV-Datei

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);
}

  • Es ist zu beachten, dass diese Funktion nicht korrekt mit Anführungszeichen in CSV umgeht. Insbesondere kann es nicht mit diesem Beispiel umgehen, wie es in Wikipedia zu finden ist: en.wikipedia.org/wiki/Comma-separated_values#Example Es gab einen offenen Fehler, aber er wurde als “wird nicht behoben” geschlossen bugs.php.net/bug.php?id=50686

    – amenthes

    7. September 2015 um 21:30 Uhr


  • Funktioniert auch nicht korrekt bei Spalten mit Zeilenumbrüchen in ihrem Inhalt

    – Professorval

    23. Juli 2021 um 0:39 Uhr

1646633050 884 So analysieren Sie eine CSV Datei mit PHP duplicate
Aldekin

Eine etwas kürzere Antwort seitdem PHP >= 5.3.0:

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

  • Beachten Sie, dass dies nicht funktioniert, wenn Sie Zeilenumbrüche in den tatsächlichen Werten haben (nicht die Zeilentrennzeichen am Ende jeder CSV-Zeile), da die file Die Funktion wird bei Zeilenumbrüchen geteilt und kennt die Anführungszeichen nicht, die CSV verwendet, um Feldwerte zu enthalten.

    – Jordan Lew

    13. Januar 2016 um 19:52 Uhr

  • @JordanLev, was empfiehlst du dann?

    – Julix

    15. Mai 2017 um 0:39 Uhr

  • @Julix verwende die akzeptierte Antwort. Diese kürzere Version ist nett, wenn Sie wissen, dass die importierten Daten niemals Zeilenumbrüche innerhalb eines einzelnen Werts haben, aber ansonsten ist die robustere Lösung die zusätzlichen Codezeilen wert.

    – Jordan Lew

    15. Mai 2017 um 3:57 Uhr

  • Am Ende habe ich vor dem Speichern in CSV codiert und beim Lesen decodiert – php.net/rawurlencode – das stellt sicher, dass keine Zeilenumbrüche auftreten, oder? – oder gehen sie ganz verloren (kann es Zeilenumbrüche in der URL-Codierung geben?)

    – Julix

    15. Mai 2017 um 4:24 Uhr


  • Diese Antwort funktioniert perfekt für neue Zeilen und nutzt die Magie der PHP-Dateifunktion. Danke

    – Madhab452

    5. August 2017 um 10:00 Uhr

Praktischer Einzeiler zum Parsen einer CSV-Datei in ein Array

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

  • Beachten Sie, dass dies nicht funktioniert, wenn Sie Zeilenumbrüche in den tatsächlichen Werten haben (nicht die Zeilentrennzeichen am Ende jeder CSV-Zeile), da die file Die Funktion wird bei Zeilenumbrüchen geteilt und kennt die Anführungszeichen nicht, die CSV verwendet, um Feldwerte zu enthalten.

    – Jordan Lew

    13. Januar 2016 um 19:51 Uhr

  • Wie verwende ich verschiedene Trennzeichen? ( ; anstatt , )

    – sdd

    3. April 2017 um 11:00 Uhr

  • Verwenden Sie Folgendes, um das Problem mit neuen Zeilen zu beheben: array_map(‘str_getcsv’, file(‘data.csv’ , FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));

    – Robert Sinclair

    7. Juni 2017 um 5:03 Uhr

  • Wissen Sie, es ist nett, den jeweiligen Autoren Anerkennung zu zollen: php.net/manual/en/function.str-getcsv.php#114764

    – xNull

    13. Juni 2017 um 11:31 Uhr

  • @Maxim Kovalevsky, wie man Überschrift oder erste Zeile überspringt

    – Krishna Jonnalagadda

    1. März 2018 um 9:44 Uhr

1646633051 89 So analysieren Sie eine CSV Datei mit PHP duplicate
Quartär

Ich habe gerade eine praktische Möglichkeit entdeckt, während des Parsens einen Index zu erhalten. Mein Verstand war überwältigt.

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

Quelle: Link

So analysieren Sie eine CSV Datei mit PHP duplicate
Angreifer

ich liebe es

$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);
}

In meinem Fall erhalte ich eine CSV-Datei über Webdienste, sodass ich die Datei auf diese Weise nicht erstellen muss. Wenn Sie jedoch mit einer Datei parsen müssen, müssen Sie sie nur als Zeichenfolge übergeben

  • Das hat bei mir nicht richtig funktioniert. Zum Beispiel dies: aaa,bbb,"ccc\nddd",eee wurde in zwei Zeilen (statt der gewünschten einen Zeile) statt in eine geparst. Es scheint, dass " wird nicht als Umschließung erkannt, wenn es innerhalb des Feldes erscheint (und nicht an dessen Anfang oder Ende). Damit $data = str_getcsv(..) kann ersetzt werden durch $data = explode(..)was meiner Meinung nach effizienter ist und die Absicht besser vermittelt …

    – Oben

    22. Mai 2020 um 0:21 Uhr


1646633053 614 So analysieren Sie eine CSV Datei mit PHP duplicate
Ranjul Arumadi

Ich habe dasselbe gesucht, ohne eine nicht unterstützte PHP-Klasse zu verwenden. Excel CSV verwendet nicht immer die Anführungszeichen-Trennzeichen und maskiert die Anführungszeichen mit “”, da der Algorithmus wahrscheinlich in den 80er Jahren oder so erstellt wurde. Nachdem ich mir mehrere .csv-Parser im Kommentarbereich von PHP.NET angesehen habe, habe ich solche gesehen, die sogar Callbacks oder eval’d-Code verwendet haben und entweder nicht wie benötigt funktionierten oder einfach überhaupt nicht funktionierten. Also habe ich meine eigenen Routinen dafür geschrieben und sie funktionieren in der einfachsten PHP-Konfiguration. Die Array-Schlüssel können entweder numerisch sein oder als Felder benannt werden, die in der Kopfzeile angegeben sind. Hoffe das hilft.

    function SW_ImplodeCSV(array $rows, $headerrow=true, $mode="EXCEL", $fmt="2D_FIELDNAME_ARRAY")
    // SW_ImplodeCSV - returns 2D array as string of csv(MS Excel .CSV supported)
    // AUTHOR: [email protected]
    // RELEASED: 9/21/13 BETA
      { $r=1; $row=array(); $fields=array(); $csv="";
        $escapes=array('\r', '\n', '\t', '\\', '\"');  //two byte escape codes
        $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code

        if($mode=='EXCEL')// escape code = ""
         { $delim=','; $enclos="""; $rowbr="\r\n"; }
        else //mode=STANDARD all fields enclosed
           { $delim=','; $enclos="""; $rowbr="\r\n"; }

          $csv=""; $i=-1; $i2=0; $imax=count($rows);

          while( $i < $imax )
          {
            // get field names
            if($i == -1)
             { $row=$rows[0];
               if($fmt=='2D_FIELDNAME_ARRAY')
                { $i2=0; $i2max=count($row);
                  while( list($k, $v) = each($row) )
                   { $fields[$i2]=$k;
                     $i2++;
                   }
                }
               else //if($fmt="2D_NUMBERED_ARRAY")
                { $i2=0; $i2max=(count($rows[0]));
                  while($i2<$i2max)
                   { $fields[$i2]=$i2;
                     $i2++;
                   }
                }

               if($headerrow==true) { $row=$fields; }
               else                 { $i=0; $row=$rows[0];}
             }
            else
             { $row=$rows[$i];
             }
    
            $i2=0;  $i2max=count($row); 
            while($i2 < $i2max)// numeric loop (order really matters here)
            //while( list($k, $v) = each($row) )
             { if($i2 != 0) $csv=$csv.$delim;

               $v=$row[$fields[$i2]];

               if($mode=='EXCEL') //EXCEL 2quote escapes
                    { $newv = '"'.(str_replace('"', '""', $v)).'"'; }
               else  //STANDARD
                    { $newv = '"'.(str_replace($escapes2, $escapes, $v)).'"'; }
               $csv=$csv.$newv;
               $i2++;
             }

            $csv=$csv."\r\n";

            $i++;
          }

         return $csv;
       }

    function SW_ExplodeCSV($csv, $headerrow=true, $mode="EXCEL", $fmt="2D_FIELDNAME_ARRAY")
     { // SW_ExplodeCSV - parses CSV into 2D array(MS Excel .CSV supported)
       // AUTHOR: [email protected]
       // RELEASED: 9/21/13 BETA
       //SWMessage("SW_ExplodeCSV() - CALLED HERE -");
       $rows=array(); $row=array(); $fields=array();// rows = array of arrays

       //escape code="\"
       $escapes=array('\r', '\n', '\t', '\\', '\"');  //two byte escape codes
       $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code

       if($mode=='EXCEL')
        {// escape code = ""
          $delim=','; $enclos="""; $esc_enclos=""""; $rowbr="\r\n";
        }
       else //mode=STANDARD 
        {// all fields enclosed
          $delim=','; $enclos="""; $rowbr="\r\n";
        }

       $indxf=0; $indxl=0; $encindxf=0; $encindxl=0; $enc=0; $enc1=0; $enc2=0; $brk1=0; $rowindxf=0; $rowindxl=0; $encflg=0;
       $rowcnt=0; $colcnt=0; $rowflg=0; $colflg=0; $cell="";
       $headerflg=0; $quotedflg=0;
       $i=0; $i2=0; $imax=strlen($csv);   

       while($indxf < $imax)
         {
           //find first *possible* cell delimiters
           $indxl=strpos($csv, $delim, $indxf);  if($indxl===false) { $indxl=$imax; }
           $encindxf=strpos($csv, $enclos, $indxf); if($encindxf===false) { $encindxf=$imax; }//first open quote
           $rowindxl=strpos($csv, $rowbr, $indxf); if($rowindxl===false) { $rowindxl=$imax; }

           if(($encindxf>$indxl)||($encindxf>$rowindxl))
            { $quoteflg=0; $encindxf=$imax; $encindxl=$imax;
              if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; }
            }
           else 
            { //find cell enclosure area (and real cell delimiter)
              $quoteflg=1;
              $enc=$encindxf; 
              while($enc<$indxl) //$enc = next open quote
               {// loop till unquoted delim. is found
                 $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//close quote
                 $encindxl=$enc; //last close quote
                 $indxl=strpos($csv, $delim, $enc+1); if($indxl===false)  { $indxl=$imax; }//last delim.
                 $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//open quote
                 if(($indxl==$imax)||($enc==$imax)) break;
               }
              $rowindxl=strpos($csv, $rowbr, $enc+1); if($rowindxl===false) { $rowindxl=$imax; }
              if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; }
            }

           if($quoteflg==0)
            { //no enclosured content - take as is
              $colflg=1;
              //get cell 
             // $cell=substr($csv, $indxf, ($indxl-$indxf)-1);
              $cell=substr($csv, $indxf, ($indxl-$indxf));
            }
           else// if($rowindxl > $encindxf)
            { // cell enclosed
              $colflg=1;
     
             //get cell - decode cell content
              $cell=substr($csv, $encindxf+1, ($encindxl-$encindxf)-1);

              if($mode=='EXCEL') //remove EXCEL 2quote escapes
                { $cell=str_replace($esc_enclos, $enclos, $cell);
                }
              else //remove STANDARD esc. sceme
                { $cell=str_replace($escapes, $escapes2, $cell);
                }
            }

           if($colflg)
            {// read cell into array
              if( ($fmt=='2D_FIELDNAME_ARRAY') && ($headerflg==1) )
               { $row[$fields[$colcnt]]=$cell; }
              else if(($fmt=='2D_NUMBERED_ARRAY')||($headerflg==0))
               { $row[$colcnt]=$cell; } //$rows[$rowcnt][$colcnt] = $cell;

              $colcnt++; $colflg=0; $cell="";
              $indxf=$indxl+1;//strlen($delim);
            }
           if($rowflg)
            {// read row into big array
              if(($headerrow) && ($headerflg==0))
                {  $fields=$row;
                   $row=array();
                   $headerflg=1;
                }
              else
                { $rows[$rowcnt]=$row;
                  $row=array();
                  $rowcnt++; 
                }
               $colcnt=0; $rowflg=0; $cell="";
               $rowindxf=$rowindxl+2;//strlen($rowbr);
               $indxf=$rowindxf;
            }

           $i++;
           //SWMessage("SW_ExplodeCSV() - colcnt = ".$colcnt."   rowcnt = ".$rowcnt."   indxf = ".$indxf."   indxl = ".$indxl."   rowindxf = ".$rowindxf);
           //if($i>20) break;
         }

       return $rows;
     }

…bob kann jetzt zu seinen Tabellenblättern zurückkehren

  • Das hat bei mir nicht richtig funktioniert. Zum Beispiel dies: aaa,bbb,"ccc\nddd",eee wurde in zwei Zeilen (statt der gewünschten einen Zeile) statt in eine geparst. Es scheint, dass " wird nicht als Umschließung erkannt, wenn es innerhalb des Feldes erscheint (und nicht an dessen Anfang oder Ende). Damit $data = str_getcsv(..) kann ersetzt werden durch $data = explode(..)was meiner Meinung nach effizienter ist und die Absicht besser vermittelt …

    – Oben

    22. Mai 2020 um 0:21 Uhr


963410cookie-checkSo analysieren Sie eine CSV-Datei mit PHP [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy