Since it seems the built-in fgetcsv does not correctly handle the CSV standard, there are suggestions for alternatives on the PHP man page for fgetcsv - here's one of them:
From http://www.php.net/manual/en/function.fgetcsv.php
The PHP's CSV handling stuff is
non-standard and contradicts with
RFC4180, thus fgetcsv() cannot
properly deal with files like this
example ...
There is a quick and dirty
RFC-compliant realization of CSV
creation and parsing:
<?php
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;
}
?>