【问题标题】:How can I change the line endings used by fputcsv?如何更改 fputcsv 使用的行尾?
【发布时间】:2012-10-04 08:08:04
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 除非用户在需要 CRLF 的 Windows 文本编辑器或一些非常旧的 Windows 应用程序中打开文件,否则它实际上并不重要......如今大多数 Windows 应用程序都可以识别一个简单的LF 代替
  • 抱歉 +1 你在 1337,最优雅的代表。但是你的问题让我很感兴趣,也没有办法改变逃生字符......
  • @MarkBaker:是的,这就是我的预期。不幸的是,他们将 CSV 导入到他们使用的一些 MIS 中,这在这方面似乎并不比记事本更智能。
  • 您是否阅读了 fputcsv 手册中的 cmets? lv.php.net/manual/en/function.fputcsv.php#90883
  • @lix: 是的,我当然有,我可以依靠你链接到的特定函数,但我想使用 fputcsv() 并在之后转换行尾,而不是复制fputcsv() 的全部功能并添加行尾转换。 PHP 用户笔记并不总是最好的资源。这就是我来这里的原因:)

标签: php csv line-endings


【解决方案1】:

您可以使用流过滤器来完成此操作。此示例写入一个物理文件,但它应该也适用于 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 系统,是吗? ;)

    至于真正的解决方案,您可以使用 Linux 程序 unix2dos(与 dos2unix 相反)而不是逐行使用 str_replace,前提是您已安装它:

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

    【讨论】:

      【解决方案3】:
      1. 在 Linux 机器上创建以 \n 行结尾的文件
      2. 将文件作为 ASCII 从 Linux 机器 FTP 到 Windows 机器
      3. 嘿,快!所有行结尾现在都在 Windows 机器上的文件中 \r\n

      【讨论】:

        【解决方案4】:

        与其写文件,更好的解决办法是使用输出缓冲

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 当从 Mac 设备生成的 csv 文件未解析时,它在我的情况下工作。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-13
          • 2012-05-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多