Csv Datei zeilenweise auslesen als Array zurück geben
KampfHitsKeks
- php
Hallo, wie meine Überschrift bereits mein Problem beschreibt bekomme ich die Daten nicht vernünftig auslesen.Zumindest müsste ich Daten die wie folgt aufgebaut sind:
dt_Jahr dt_Nummer dt_Kilometer
01022008 15795464 4564km
.
.
.
Diese Daten sollten dann zeilenweise ausgelesen werden, und als Array zurückgegeben werden leider raffe ich das nicht so ganz.
wäre schön wenn mir wer weiterhelfen könnte. Hier der aktuelle Codeschnippsel.(Die Ausgabe soll als wiederkehrende Funktion auftauchen da dies öfter verwendet wird)
function holeDaten($filename, &$_buffer, $maxrecsize=2048) ##function öffnen
{
$fh = fopen($filename,'r');
$_rec = array();
while ($false !==($rec = fgetcsv($fh, $maxrecsize, ';', '"'))
{
$_buffer[] = $_rec;
}
fclose($fh);
return 0;
}
$_buffer = array();
$err_hd = holeDaten('xxx.csv',$_buffer);
if ($err_hd == 0)
{
echo "<pre>\r\n";
echo print_r($_buffer,1);
echo "</pre>\r\n";
}
else
{
echo "<p>Fehler beim Lesen von ".$filename.": $err_hd <p>\r\n";
}
MfG
KampfHitsKeks
Hello,
da erkenne ich doch meinen Code :-)
Ist aber ein fehler drin.
Zum Debuggen bitte immer im Script oder im Verzeichnis
Error_Reporting(E_ALL);
benutzten.
function holeDaten($filename, &$_buffer, $maxrecsize=2048) ##function öffnen
{
$fh = fopen($filename,'r');
$_rec = array();
while ($false !==($_rec = fgetcsv($fh, $maxrecsize, ';', '"'))
# ^
{
$_buffer[] = $_rec;
}
fclose($fh);
return 0;
}$_buffer = array();
$err_hd = holeDaten('xxx.csv',$_buffer);
if ($err_hd == 0)
{
echo "<pre>\r\n";
echo htmlspecialchars(print_r($_buffer,1));
echo "</pre>\r\n";
}
else
{
echo "<p>Fehler beim Lesen von ".$filename.": $err_hd <p>\r\n";
}
Schau mal, ob es so funktioniert.
Liebe Grüße aus Syburg
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
Nur selber lernen macht schlau
<http://bergpost.annerschbarrich.de>
Leider bekomme ich wenn ich Error_Reporting(E_ALL); benutze keine Ausgabe.
Hello,
Leider bekomme ich wenn ich Error_Reporting(E_ALL); benutze keine Ausgabe.
Wie? Gar keine Ausgabe?
Liebe Grüße aus Syburg
Tom vom Berg
Hello,
»»
»» Leider bekomme ich wenn ich Error_Reporting(E_ALL); benutze keine Ausgabe.Wie? Gar keine Ausgabe?
Liebe Grüße aus Syburg
Tom vom Berg
Nein, die Seite bleibt komplett weiß. Problem ist wenn ich den kleinen Teil von Joachim benutze kann ich dies nicht weiterverwenden (die Funktion soll später eine Tabelle bilden) und von daher brauch ich das einzelne Auslesen dieser Daten.
Hello,
»» Leider bekomme ich wenn ich Error_Reporting(E_ALL); benutze keine Ausgabe.
Wie? Gar keine Ausgabe?
Nein, die Seite bleibt komplett weiß. Problem ist wenn ich den kleinen Teil von Joachim benutze kann ich dies nicht weiterverwenden (die Funktion soll später eine Tabelle bilden) und von daher brauch ich das einzelne Auslesen dieser Daten.
Wo hast Du denn den Codeschnipsel gefunden? Das war sicherlich nur eine Skizze, oder er sit nicht vollständig.
Anschließend das korrigierte und _ausgetestete_ Script:
<?php ### getcsv.php ###
error_reporting(E_ALL);
ini_set('display_errors', 1);
#------------------------------------------------------------------------------
function holeDaten($filename, &$_buffer, $maxrecsize=2048) ##function öffnen
{
$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);
return 0;
}
#==============================================================================
#==============================================================================
$_buffer = array();
$err_hd = holeDaten('xxx.csv',$_buffer);
if ($err_hd == 0)
{
echo "<pre>\r\n";
echo htmlspecialchars(print_r($_buffer,1));
echo "</pre>\r\n";
}
else
{
echo "<p>Fehler beim Lesen von ".$filename.": $err_hd <p>\r\n";
}
?>
und hier ein paar Musterdaten (einfach mit Copy & Paste in eine ASCII-Datei xxx.csv schieben:
1234;2348;1388
;;;"Hallo";"Thomas"
"CSV-Test";"falsche Zeilenlänge";9999;1355
"Text mit
Umbruch und sonstigen ""Schweinereien"";";88888;"Ende"
Das Auffüllen auf eine canonische Tabelle musst Du bei CSV noch selber erledigen. Dazu musst Du aber ersteinmal wissen, welche Zeile die meisten Elemente hat, damit du die anderen Zeilen mite leeren Array-Elementen auffülen kannst und ggf. leere Zeilen entfernen kannst.
Das könnte man der Funktion hole_daten() auch noch beibringen.
Liebe Grüße aus Syburg
Tom vom Berg
»»Wo hast Du denn den Codeschnipsel gefunden? Das war sicherlich nur eine Skizze, oder er sit nicht vollständig.
Den Codeschnipsel hatte ich auch hier im Forum gefunden, hatte mich schon ein bisschen umgekuckt, aber nicht das direkt Problem gefunden.
Ja jetzt bekomme ich auch keine Fehler und sogar eine Ausgabe.
Werde mir aber zur Verständnis den Code nocheinmal genauer unter die Lupe nehmen.Die Sache mit der Tabelle werde ich mir nocheinmal anschauen.
Danke für die Hilfe
MfG
KampfHitsKeks
Hello,
Werde mir aber zur Verständnis den Code nocheinmal genauer unter die Lupe nehmen.Die Sache mit der Tabelle werde ich mir nocheinmal anschauen.
Wenn Du Fragen zum Verständnis hast, dann bitte melden.
Es ist ja ausnahmsweise nicht ausführlich kommentiert im Moment.
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()".
Liebe Grüße aus Syburg
Tom vom Berg
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
Hi,
Diese Daten sollten dann zeilenweise ausgelesen werden, und als Array zurückgegeben werden
Du kennst file?
Dann teste doch mal $x = file("myfile.src"); echo "<pre>"; print_r($x); echo "</pre>";
Gruesse, Joachim
Hello,
Diese Daten sollten dann zeilenweise ausgelesen werden, und als Array zurückgegeben werden
Du kennst file?Dann teste doch mal $x = file("myfile.src"); echo "<pre>"; print_r($x); echo "</pre>";
Das ist keine gute Idee für eine sichere Applikation.
File() ist eine namensbasierte Funktion, mit der es daher sehr schwer ist, ein sauberes konkurrierendes Arbeiten zu ermöglichen.
Nach POSIX müssen Streams zwar während des Lesens und Schreibens gelockt werden, also bestehende Sperrena uch berücksichtigen, davon haben aber die namensbasierten Funktionen von PHP bisher wenig mitbekommen...
Außerdem unterliegt das lesen von CSV-Dateien ganz anderen Gesetzen, als sie File() erfüllen kann. Dass im von KampfHitsKeks genannten Datenbeispiel keine Fehler auftreten werden, bedeutet ja nicht, dass er später nicht noch andere Daten hinzufügen will, die dann Fehler verursachen, also die CSV-Regeln einhalten sollten.
Liebe Grüße aus Syburg
Tom vom Berg
Hi,
Nach POSIX müssen Streams zwar während des Lesens und Schreibens gelockt werden,
verstehe ich jetzt nicht. Sollte man für sowas nicht eh mit flock arbeiten?
Gruesse, Joachim
Hello,
Nach POSIX müssen Streams zwar während des Lesens und Schreibens gelockt werden,
verstehe ich jetzt nicht. Sollte man für sowas nicht eh mit flock arbeiten?
ja, sagte ich doch. File() lässt dies als namensbasierte Hüllfunktion aber nicht direkt zu. Indirektes Locking führt aber meistens zu Fehlern, zumindest bei gemeinsamen Datenbeständen.
Dafür arbeitet PHP aber mit Streams. File() könnte also mittels einer einzigen Streamanweisung das gesamte File einlesen und puffern. Dann könnte file() auch das nach POSIX vorgeschriebene Locking für Streams beachten.
Liebe Grüße aus Syburg
Tom vom Berg