Bug #1443: Function doesn't follow csv spec
| From: | C dot Just at its dot uq dot edu dot au | Date: | Mon, 24 May 1999 03:13:11 +0000 |
| Subject: | Bug #1443: Function doesn't follow csv spec | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-5922@lists.php.net to get a copy of this message | ||
From: C.Just@its.uq.edu.au
Operating system: All
PHP version: 3.0.8
PHP Bug Type: Misbehaving function
Bug description: Function doesn't follow csv spec
The Function though excellent doesn't follow the specs for csv's.
A csv should allow newlines within a quoted field.
I have written the workable solution in PHP code but don't feel confident enough to convert it
to c code :)
Here is a test csv file
--------------------------------
this,34,23,"this has ""quotes""
and
enters"
field,45,3,no_quotes
"this, has a comma",45,34,"comma and , some ""quotes"""
"THIS_ENDS_wITH_A_QUOTE""","45""",87,"COUPLE, OF ,
COMMAS AND QUOTES"""
",commafirst",89,7,"""quotes first"
normal,"""9",3,
--------------------------------
Here is the working code.
----------------------------------------------------------------------------
function fgetcsvnew($filepointer){
// INCASE FORMAT COMING FROM A WINDOWS MACHINE
$importfile[$i] = ereg_replace("\r\n","\n",$importfile[$i]);
$endofrecord = 0;
$resultcounter = 0;
while (!$endofrecord && ($currentline = fgets($filepointer,2048))){
// LOOP THRU CURRENT LINE
for($j=0; $j<strlen($currentline); $j++){
// CHECK TO SEE IF THE CURRENT POSITION IS WITHIN A QUOTED FIELD
switch($midfield){
case 0:
// THIS MARKS THE BEGINNING OF A QUOTED FIELD
if ($currentline[$j] == "\""){
$midfield = 1;
// THIS MARKS THE END OF THE CURRENT UNQUOTED FIELD
}elseif($currentline[$j] == ","){
$midfield = 0;
$result = $buffer;
$buffer = "";
// THIS MARKS THE END OF THE CURRENT RECORD
}elseif($currentline[$j] == "\n"){
$midfield = 0;
$result = $buffer;
$buffer = "";
$endofrecord = 1;
}else{
// STILL WITHIN A UNQUOTED FIELD SO STORE IN BUFFER
$buffer .= $currentline[$j];
}
break;
case 1:
// CHECKS FOR THE FIRST QUOTE
if ($currentline[$j] == "\""){
// CHECKS FOR THE SECOND ESCAPED QUOTE
if ($currentline[$j+1] == "\""){
// ADD THE ESCAPED QUOTE TO THE BUFFER
$buffer .= "\"";
$j++; // SKIP LINE POINTER FORWARD ONE.
// THIS MARKS THE END OF A QUOTED FIELD.
}else{
$midfield = 0;
$result = $buffer;
$buffer = "";
}
// STILL WITHIN A QUOTED FIELD SO STORE IN BUFFER
}else{
$buffer .= $currentline[$j];
}
break;
}
// CHECK TO SEE IF RESULT EXISTS, THE TRIM IS NEEDED AS THE END OF THE RECORD CONTAINS A \n
AND THIS SHOULD BE IGNORED.
if(trim($result)){
$resultarray[$resultcounter] = $result;
$resultcounter++;
$result = 0;
}
}
}
if (is_array($resultarray)){
return($resultarray);
}else{
return(-1);
}
}
// test for the function above
$fp = fopen("test.csv", "r");
$k = 0;
while(is_array($test = fgetcsvnew($fp)) && ($k++<10)){
echo "---$k--------------------------------------------\n";
for ($i=0; $i<count($test);$i++){
echo "**\n".$test[$i]."\n";
}
}
--------------------------------------------------------------
--
PHP Development Mailing List http://www.php.net/
To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net
For help: php-dev-help@lists.php.net