tags:

views:

52

answers:

4

Currently I am working on a PHP script to output a CSV file from entries in a MySQL database. My problem lies in how to correctly output the values. Many of the entries in the MySQL database will contain commas and quotes, which destroy the format of the CSV file if I just plainly print them out to the file.

I'm aware that I can surround the text in quotes, but the entries that contain quotes would mess up the format of the file.

My question is, what can I do to keep this from happening?

Also, do new lines affect the interpretation of the file?

In addition, I'd rather not use the fputcsv function in PHP. I'm attempting to make the PHP script output the contents of the file (with appropriate headers) rather than write to a new file.

Thanks in advance!

Regards, celestialorb

+3  A: 

fputcsv is your friend

adam
"In addition, I'd rather not use the fputcsv function in PHP."
meagar
Ah, not sure how I missed that. I'd still argue that it's easier to write a temp file (using `tempnam`) and then output that.
adam
A: 

I have found tab separated value files to be helpful in these situations. TSV is less susceptible to the issues with commas etc in your data.

Icode4food
A: 

The process is called escaping, and most parsers (included PHP's) use the backslash to escape characters:

"This string contains literal \"quotes\" denoted by backslashes"

You can escape characters in a string with addcslashes:

// escape double-quotes
$string = addcslashes('this string contains "quotes"', '"');

echo $string; // 'this string contains \"quotes\"'

Given an array of data you want to separate by commas, you can do the following:

// Escape all double-quotes
foreach ($data as $key => $value)
  $data[$key] = addcslashes($value, '"');

// Wrap each element in double quotes
echo '"' . implode('", "', $data), '"';
meagar
Wouldn't a program such as Excel not realize they those quotes are escaped though? It would read in "this string contains \" as the value?
celestialorb
@cele The need to escape quotes inside strings is universal, and Excel will have some way of doing so. It may allow you to specify the escape character, or use another common way of escaping quotes in MS software where one quote is replaced with three: `"` becomes `"""`.
meagar
@cele The simplest way to find out would be to create an Excel file, throw some quotes in it, and export it as a CSV.
meagar
I realize there's no CSV standard but RFC 4180: http://www.ietf.org/rfc/rfc4180.txt recommends two double quotes as an escaped double quote. I confirmed that Excel 2007 recognizes the two-double-quote escape but treats \" as literal text. So the field - "Super" Bad - is encoded """Super"" Bad". It's not guaranteed to work everywhere, but nothing is given there's no spec.
Corbin March
+1  A: 

I think your dismissal of fputcsv might have been premature. In the comments of the fputcsv manual there's an example where they use fputcsv to output to the browser instead of a file. http://php.net/manual/en/function.fputcsv.php

Here is that code, plus some headers to show that it does indeed prompt the user to download a csv file.

$mydata = array(
 array('data11', 'data12', 'data13'),
 array('data21', 'data22', 'data23'),
 array('data31', 'data32', 'data23'));
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"my-data.csv\"");
outputCSV($mydata);

function outputCSV($data) {
    $outstream = fopen("php://output", 'w');
    function __outputCSV(&$vals, $key, $filehandler) {
        fputcsv($filehandler, $vals, ';', '"');
    }
    array_walk($data, '__outputCSV', $outstream);
    fclose($outstream);
}
Bob Baddeley
Thanks, I must've missed that part of the documentation. This is exactly what I was looking for. :)
celestialorb