10

I want to output a query to a csv file with " enclosures around all fields.

The following:

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$strFeederFileName.'');

$output = fopen('php://output', 'r+');
$fileheader = array( "FH", "READY TO PAY", "RTP060620134", "060620134RWKN", "");
fputcsv($output, $fileheader, ",", '"');

Outputs this:

FH,"READY TO PAY",RTP060620134,060620134RWKN

but I need it to be:

"FH","READY TO PAY","RTP060620134","060620134RWKN"

Any ideas why it's not adding enclosures to fields 1, 3 & 4?

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Dion
  • 203
  • 2
  • 5
  • 14
  • No such option in php ... but see http://stackoverflow.com/questions/2514597/php-fputcsv-and-enclosing-fields to give you an alternate implementation. – Orangepill Jun 06 '13 at 21:00
  • 2
    There is no need to as it doesn’t contain characters like whitespace, quotes, or the separating character. – Gumbo Jun 06 '13 at 21:00

3 Answers3

2

fputcsv is pretty smart at guessing which columns need to have brackets and don't in order to keep the CSV valid.

At the moment it's outputting valid CSV.

fputcsv doesn't provide an option to force enclosing in quotes, it'd probably be good to know why you need them to all be in quotes?

rob_mccann
  • 1,237
  • 2
  • 11
  • 16
  • it's a feeder file to import into Oracle (which is very specific about which fields it is expecting quotes around). I guess it's not a genuine csv file in that case but is there any other option? – Dion Jun 06 '13 at 21:05
1

Gumby's comment is correct - if it doesnt need to enclose in quotes, it wont. You could do something like set the enclosure to an empty string, and put them on yourself:

$fileheader = array( "FH", "READY TO PAY", "RTP060620134", "060620134RWKN", "");
for($i=0; $i<count($fileheader); $i++) 
{ 
    $fileheader[i] = '"' . $fileheader[$i] . '"'; 
}
fputcsv($output, $fileheader, ",", '');
dave
  • 62,300
  • 5
  • 72
  • 93
0

Thanks all for your help. I used a combination of answers because I needed to be able to choose which fields to enclose and which not to. I added a unique string (xxx) around the fields that I don't want to enclose and using str_replace before writing the line to the file:

 header('Content-Type: text/csv; charset=utf-8');
 header('Content-Disposition: attachment; filename='.$strFeederFileName.'');

 function dumbcsv($file_handle, $data_array, $enclosure, $field_sep, $record_sep)
 {
 dumbescape(false, $enclosure);
 $data_array=array_map('dumbescape',$data_array);

 $line = $enclosure 
     . implode($enclosure . $field_sep . $enclosure, $data_array)
     . $enclosure . $record_sep;

 $line = str_replace('"xxx', '', $line);
 $line = str_replace('xxx"', '', $line);

 return $line;
}

function dumbescape($in, $enclosure=false)
  {
  static $enc;
  if ($enclosure===false) {
    return str_replace($enc, '\\' . $enc, $in);
  }
  $enc=$enclosure;
}

$output = fopen('php://output', 'r+');
$rows_csv = mysql_query('SELECT * FROM  tblfeeder');

//Add file header
$fileheader = array( "FH", "READY TO PAY", $fileheader, $strOracleBatchName);
$line = dumbcsv($output, $fileheader, "\"", ",", "\r\n" );
fwrite($output, $line);

// loop over the rows, outputting them
while ($row_csv = mysql_fetch_assoc($rows_csv)) fwrite($output, dumbcsv($output,  $row_csv, "\"", ",", "\r\n" ));

//Add file footer
$filefooter = array( "IF", "xxx".$batchtotal."xxx", "xxx".$invnum."xxx");
$line = dumbcsv($output, $filefooter, "\"", ",", "\r\n" );
fwrite($output, $line);
Dion
  • 203
  • 2
  • 5
  • 14