note 98800 added to function.fgetcsv
| From: | donotspamaleskeatlivedotru at osu1 dot php dot net | Date: | Thu, 08 Jul 2010 13:38:51 +0000 |
| Subject: | note 98800 added to function.fgetcsv | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-170786@lists.php.net to get a copy of this message | ||
The PHP's CSV handling stuff is non-standard and contradicts with RFC4180, thus fgetcsv()
cannot properly deal with files like this example from Wikipedia:
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very
Large""","",5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00
Please note: the enclosure symbol is doubled inside fields, field data can contain linebreaks, and
there is no real escape symbol. Also, fputcsv() creates non-standard CSV files.
There is a quick and dirty RFC-compliant realization of CSV creation and parsing:
function array_to_csvstring($items, $CSV_SEPARATOR = ';', $CSV_ENCLOSURE =
'"', $CSV_LINEBREAK = "\n") {
$string = '';
$o = array();
foreach ($items as $item) {
if (stripos($item, $CSV_ENCLOSURE) !== false) {
$item = str_replace($CSV_ENCLOSURE, $CSV_ENCLOSURE . $CSV_ENCLOSURE, $item);
}
if ((stripos($item, $CSV_SEPARATOR) !== false)
|| (stripos($item, $CSV_ENCLOSURE) !== false)
|| (stripos($item, $CSV_LINEBREAK !== false))) {
$item = $CSV_ENCLOSURE . $item . $CSV_ENCLOSURE;
}
$o[] = $item;
}
$string = implode($CSV_SEPARATOR, $o) . $CSV_LINEBREAK;
return $string;
}
function csvstring_to_array(&$string, $CSV_SEPARATOR = ';', $CSV_ENCLOSURE =
'"', $CSV_LINEBREAK = "\n") {
$o = array();
$cnt = strlen($string);
$esc = false;
$escesc = false;
$num = 0;
$i = 0;
while ($i < $cnt) {
$s = $string[$i];
if ($s == $CSV_LINEBREAK) {
if ($esc) {
$o[$num] .= $s;
} else {
$i++;
break;
}
} elseif ($s == $CSV_SEPARATOR) {
if ($esc) {
$o[$num] .= $s;
} else {
$num++;
$esc = false;
$escesc = false;
}
} elseif ($s == $CSV_ENCLOSURE) {
if ($escesc) {
$o[$num] .= $CSV_ENCLOSURE;
$escesc = false;
}
if ($esc) {
$esc = false;
$escesc = true;
} else {
$esc = true;
$escesc = false;
}
} else {
if ($escesc) {
$o[$num] .= $CSV_ENCLOSURE;
$escesc = false;
}
$o[$num] .= $s;
}
$i++;
}
// $string = substr($string, $i);
return $o;
}
References:
RFC4180 - http://tools.ietf.org/html/rfc4180
Wikipedia - http://en.wikipedia.org/wiki/Comma-separated_values#Example
Also, there is complete solution of CSV handling at http://code.google.com/p/parsecsv-for-php/
----
Server IP: 78.41.104.8
Probable Submitter: 80.82.166.230
----
Manual Page -- http://www.php.net/manual/en/function.fgetcsv.php
Edit -- https://master.php.net/note/edit/98800
Del: integrated -- https://master.php.net/note/delete/98800/integrated
Del: useless -- https://master.php.net/note/delete/98800/useless
Del: bad code -- https://master.php.net/note/delete/98800/bad+code
Del: spam -- https://master.php.net/note/delete/98800/spam
Del: non-english -- https://master.php.net/note/delete/98800/non-english
Del: in docs -- https://master.php.net/note/delete/98800/in+docs
Del: other reasons-- https://master.php.net/note/delete/98800
Reject -- https://master.php.net/note/reject/98800
Search -- https://master.php.net/manage/user-notes.php