note 42752 added to function.explode
| From: | o dot vogel at rn2 dot php dot net | Date: | Thu, 27 May 2004 21:20:26 +0000 |
| Subject: | note 42752 added to function.explode | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-70214@lists.php.net to get a copy of this message | ||
Here is an extension of the cvs - function. This function can handle a complete file (not only a
string). It handles also that the first line of the file includes the names of the cells (the
returned array uses the names of the cells as key) - and it handles multi - line content of a cell
(in Excel you can insert multible lines in ONE cell).
Example:
<<file:>>
firstname;lastname;notice
Oliver;Vogel;"this notice
has 3
lines!"
Meins;Klaus;this notive has 1 line
<<return array:>>
$res[0]['firstname'] = "Oliver"
$res[0]['lastname'] = "Vogel"
$res[0]['notice" ="this notice\nhas 3\nlines!"
$res[1]['firstname] = ....
the code: (sorry about the german comments - i AM a german ;-)
<?php
//Explode CSV (MS Excel) string
function csv_explode($str, $delim = ',', $qual = "\"") {
/**
* Länge einmalig berechnen
*/
$len = strlen($str);
/**
* Parser vorinitialisieren
*/
$inside = false;
$cell = '';
$row = 0;
$column = 0;
/**
* Über den gesamten übergebenen String und zerlegen
*/
for ($i = 0; $i < $len; ++$i) {
/**
* Sollte ich einen Trenner AUSSERHALB der "Umklammerung" finden, dann trennt dieser
* die einzelnen Zellen voneinander, d.h. den bisherigen Inhalt der Zelle in das Array
* speichern und danach löschen. Achtung: Die Zelle ist entweder zu ende, wenn ein Trenner-
* Zeichen (",") kommt, oder wenn die Zeile zu ende ist (Zeilenvorschub)
*/
if ((($str[$i] == $delim) or ($str[$i] == "\n")) and
($inside == False)) {
/**
* Den Inhalt der Zelle in das Array schreiben. Sollte es sich dabei um die 1. Zeile
* handeln (Index = 0), dann ist der Inhalt der Zelle = dem Zellennamen. D.h. in Zeile
* 0 baue ich das Array der Namen auf, danach baue ich das eigentliche Rückgabe - Array auf
*/
if ($row == 0) {
$cellNames[$column] = $cell;
} else {
$out[$row - 1][$cellNames[$column]] = $cell; // -1, da Zeile 1 = Index 0 !
}
/**
* Diese Zelle ist abgearbeitet
*/
$cell = '';
$column += 1;
/**
* Sollte der Trenner gleich noch das Zeilenende gewesen sein, ist auch die Zeile
* abgearbeitet, d.h. die SPalte fängt wieder von vorne an.
*/
if ($str[$i] == "\n") {
$row += 1;
$column = 0;
}
} else if ($inside and
($str[$i] == $qual) and
(($i < $len) and ($str[$i+1]==$qual))) {
/**
* Ich befinde mich innerhalb der "Umklammerung", habe ein " gefunden und das
nächste Zeichen
* das kommt ist ebenfalls ein ", d.h. ich habe "" gefunden. Dies muss ich zu
" reduzieren,
* d.h. das Zeichen hinzufügen und das nächste Zeichen überspringen
*/
$cell .= $qual;
++$i;
} else if ($str[$i] == $qual) {
/**
* Ich habe ein " gefunden und danach kommt KEIN zweites ", d.h. ich habe ein
EINZELNES
* " gefunden, d.h. die "Umklammerung ändert sich (das " selber ist ein
Metazeichen, d.h.
* nicht hinzufügen
*/
$inside = !$inside;
} else if ($str[$i] == "\r") {
/**
* Es handelt sich um einen Wagenrücklauf. Da dieser in Unix nicht vorkommt und in Windows
* von einem Zeilenumbruch begleitet wird, kann dieses Zeichen einfach ignoriert werden
* (der Zeilenvorschub wird bereits oben behandelt)
*/
} else {
/**
* Es handelt sich nicht um einen Sonderfall, also ist es ein "normales" Zeichen,
also
* einfach zum Zell-Inhalt hinzufügen
*/
$cell .= $str[$i];
}
}
/**
* Fertig. Da die letzte Zeile immer mit einem Zeilenumruch endet, habe ich auch dne Inhalt der
* letzten Zelle beriets bearbeitet, also muss ich hier nichts weiter mehr tun, als die Funktion
* zu beenden
*/
return $out;
} /*-------csv_explode()------------*/
//Test...
//--- Holen ---
$content = file('C:/tmp/Mappe1.csv');
//--- Verbinden ---
$csv_str = implode('', $content);
$res = csv_explode($csv_str, ';');
print_r($res);
?>
----
Manual Page -- http://www.php.net/manual/en/function.explode.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+42752
Delete -- http://master.php.net/manage/user-notes.php?action=delete+42752&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+42752&report=yes
Search -- http://master.php.net/manage/user-notes.php