Tom: Csv Datei zeilenweise auslesen als Array zurück geben, Korrektur

Beitrag lesen

Hello,

Beim lesen von CSV mit der Funktion fgetcsv() wird nicht auf die einheitliche Ausformung der Datrensätze geachtet. Es können also sowohl welche mit weniger oder mehr Feldern enthalten sein, als auch die Datentypen (CSV kennt eigentlich nur Text und Numerisch" innerhalb der Sätze vermischt/vertauscht  werden. Das ist dann natürlich für die Weiterverarbeitung der Daten lästig.

Eine CSV-Datei genügt also von alleine nicht den Anforderungen an eine saubere (typenreine) Datentabelle. Diese Forderung zu überprüfen und durchzusetzen wäre also auch noch eine Aufgabe für "hole_daten()".

habe noch ein bisschen damit gebastelt:

#------------------------------------------------------------------------------
function holeDaten($filename, &$_buffer, $delete_empty_rows=true, $maxrecsize=2048)
{
   $fh = fopen($filename,'r');
   if (!$fh) { return 2; }       ## Fehlercode 2 für "kann nicht öffnen" zurückgeben
   if (!flock($fh, LOCK_SH))
   {
       flcose($fh);
       return 5;                ## Fehlercode 5 für "kann nicht sperren" zurückgeben
   }

$_rec = array();

while (false !==($_rec = fgetcsv($fh, $maxrecsize, ';', '"')))
   {
       $_buffer[] = $_rec;
   }
   fclose($fh);

### Tabelle auf Breite auffüllen.
   ### dazu benötige wir die breiteste Zeile

$cols = 0;
   foreach($_buffer as $_rec)
   {
       $cols = max($cols,count($_rec));
   }

### Zeilen auf gleiche Breite auffüllen

foreach($_buffer as $key => $_rec)
   {

##       if ($delete_empty_rows and (count($_rec) == 1) and is_null($_rec[0]) )
##       is_null funktioniert hier nicht. Fehler von fgetcsv()

if ($delete_empty_rows and (count($_rec) == 1) and (strlen($_rec[0]) == 0) )
       {
           echo "Hallo";
           unset($_buffer[$key]);
       }
       else
       {
           $plus = $cols - count($_buffer[$key]);
           if ($plus > 0)
           {
               $_buffer[$key] += array_fill(count($_buffer[$key]), $plus, '');
           }
       }
   }

return 0;
}
#-----------------------------------------------------------------------------

und dabei zwei Fehler in fgetcsv() gefunden:

1. fgetcsv() gibt auch die numerischen Felder als Strings zurück.
   Numerische sind solche, die _nicht_ in Anführungszeichen stehen und
   vollständig numerisch auswertbar sind

Ok, damit kann man leben...

2. fgetcsv() gint leere Zeilen nicht als Array mit einem Element mit
   Inhalt NULL zurück, sondern mit einem Element mit dem Wert '' (Leerstring)

Das ist nicht so schön, da man dadurch nicht unterscheiden kann zwischen
   echten Leerzeilen und solchen, die nur ein Feld mit "" (Leerstring) enthalten.

die beiden eingebetteten Funktionalitäte für "Breite ermitteln" und "Breite auffüllen" sollte man ggf. auch als einzelne Funktionen deklarieren.

Das Auffüllen des Arrays halte ich an dieser Stelle auch nicht unbedingt für sinnvoll, wenn auch für gute Stapelverarbeitung (EVA) konsequent. Es würde reichen, das ggf. später beim Aufbau der HTML-Tabelle zu berücksichtigen, also der Ausgabe.

Liebe Grüße aus Syburg

Tom vom Berg

--
Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de