我创建了一个CSV文件供我们的客户使用
$output = fopen('php://output', 'w');
并使用fputcsv()
将数据写入客户端下载的CSV文件。
我在Linux上运行PHP,因此很多Windows应用程序都不解释行结尾。
我可以将CSV文件写入服务器上的目录,读回来并执行str_replace()
从\n
到\r\n
,但这似乎是解决问题的一种相当笨重的方式。有没有办法在不创建物理文件的情况下执行转换?
您可以使用流过滤器来完成此任务。此示例写入物理文件,但它也适用于php://output
。
// 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);
不确定你是否可以用PHP本身做到这一点。可能有一种方法可以改变PHP的EOL文件编写,但它可能与系统有关。你没有可以ping的Windows系统,对吗? ;)
至于一个真正的解决方案,而不是str_replace
逐行,你可以使用Linux程序unix2dos
(dos2unix
的反面)假设你安装它:
fputcsv($fh ...)
exec("unix2dos " . escapeshellarg($filename));
如果在读取Macintosh计算机上或由Macintosh计算机创建的文件时PHP无法正确识别行结尾,则启用auto_detect_line_endings运行时配置选项可能有助于解决问题。 ini_set(“auto_detect_line_endings”,true);
而不是编写文件,更好的解决方案是使用输出缓冲
function output($buffer) {
return str_replace("\r", "\r\n", $buffer);
}
ob_start('output');
fputcsv(....);