问题
I create a CSV file for download by our client using
$output = fopen('php://output', 'w');
and using fputcsv()
to write data to a CSV file which is downloaded by the client.
I am running PHP on Linux and consequently the line endings are not interpreted by many Windows applications.
I could write the CSV file to a directory on the server, read it back in and perform a str_replace()
from \n
to \r\n
, but this seems a rather clunky way of solving the problem. Is there a way to perform the conversion without creating a physical file?
回答1:
You could use stream filters to accomplish this. This example writes to a physical file, but it should work fine for php://output
as well.
// filter class that applies CRLF line endings
class crlf_filter extends php_user_filter
{
function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
// make sure the line endings aren't already CRLF
$bucket->data = preg_replace("/(?<!\r)\n/", "\r\n", $bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
// register the filter
stream_filter_register('crlf', 'crlf_filter');
$f = fopen('test.csv', 'wt');
// attach filter to output file
stream_filter_append($f, 'crlf');
// start writing
fputcsv($f, array('1 1', '2 2'));
fclose($f);
回答2:
Not sure if you can do this with PHP itself. There may be a way to change PHP's EOL for file writing, but it's probably system dependent. You don't have a windows system you could ping, do you? ;)
As for a real solution, instead of str_replace
line-by-line, you could use the Linux program unix2dos
(inverse of dos2unix
) assuming you have it installed:
fputcsv($fh ...)
exec("unix2dos " . escapeshellarg($filename));
回答3:
- Create the file with \n line endings on a Linux machine
- FTP the file as ASCII from the Linux machine to a Windows machine
- Hey presto! All line endings are now \r\n in the file on the Windows machine
回答4:
If PHP is not properly recognizing the line endings when reading files either on or created by a Macintosh computer, enabling the auto_detect_line_endings run-time configuration option may help resolve the problem. ini_set("auto_detect_line_endings", true);
回答5:
Rather than writing the file, a better solution is to use output buffering
function output($buffer) {
return str_replace("\n", "\r\n", $buffer);
}
ob_start('output');
fputcsv(....);
来源:https://stackoverflow.com/questions/12722894/how-can-i-change-the-line-endings-used-by-fputcsv