如何更改fputcsv使用的行结尾?

问题描述 投票:7回答:5

我创建了一个CSV文件供我们的客户使用

$output = fopen('php://output', 'w');

并使用fputcsv()将数据写入客户端下载的CSV文件。

我在Linux上运行PHP,因此很多Windows应用程序都不解释行结尾。

我可以将CSV文件写入服务器上的目录,读回来并执行str_replace()\n\r\n,但这似乎是解决问题的一种相当笨重的方式。有没有办法在不创建物理文件的情况下执行转换?

php csv line-endings
5个回答
18
投票

您可以使用流过滤器来完成此任务。此示例写入物理文件,但它也适用于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);

2
投票

不确定你是否可以用PHP本身做到这一点。可能有一种方法可以改变PHP的EOL文件编写,但它可能与系统有关。你没有可以ping的Windows系统,对吗? ;)

至于一个真正的解决方案,而不是str_replace逐行,你可以使用Linux程序unix2dosdos2unix的反面)假设你安装它:

fputcsv($fh ...)
exec("unix2dos " . escapeshellarg($filename));

1
投票
  1. 在Linux机器上使用\ n行结尾创建文件
  2. 将文件作为ASCII从Linux机器FTP到Windows机器
  3. 嘿presto!所有行结尾现在都在Windows机器上的文件中\ r \ n

0
投票

如果在读取Macintosh计算机上或由Macintosh计算机创建的文件时PHP无法正确识别行结尾,则启用auto_detect_line_endings运行时配置选项可能有助于解决问题。 ini_set(“auto_detect_line_endings”,true);


-2
投票

而不是编写文件,更好的解决方案是使用输出缓冲

function output($buffer) {
    return str_replace("\r", "\r\n", $buffer);
} 

ob_start('output');
fputcsv(....);
© www.soinside.com 2019 - 2024. All rights reserved.