在PHP中捕获文件输出(fputcsv)

时间:2009-01-06 19:31:19

标签: php

我正在尝试捕获fputcsv()的输出,以便使用gzwrite()实际写入制表符分隔文件。基本上,我正在查询数据库,我想将这些行放入一个gzip压缩的CSV文件中,我宁愿使用fputcsv()而不是实际附加"\t""\n"。我可以通过输出缓冲或类似的东西以某种方式做到这一点吗?

以下是我所拥有的基本概要:

$results = get_data_from_db();
$fp = gzopen($file_name, 'w');
if($fp) {
    foreach ($results as $row) {
        ???//something with gzwrite() ?
    }
    gzclose($fp);
}

谢谢!

编辑:我的理解是gzwrite()需要用来实际写入文件才能实际被gzip压缩 - 这是不正确的?

4 个答案:

答案 0 :(得分:16)

正如php.net所述,您可以尝试这个小技巧:

<?php
// output up to 5MB is kept in memory, if it becomes bigger
// it will automatically be written to a temporary file
$csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');

fputcsv($csv, array('blah','blah'));

rewind($csv);

// put it all in a variable
$output = stream_get_contents($csv);
?>

这实际上是你试图避免的(捕获输出),但捕获是一个非常强大的工具,所以为什么不使用它呢?

答案 1 :(得分:2)

也许我误解了这个问题,但fputcsv()对文件句柄进行操作,这就是gzopen返回的内容,所以你可以这样做:

$results = get_data_from_db();
$fp = gzopen($file_name, 'w');
if($fp) {
    foreach ($results as $row) {
        fputcsv($fp, $row);
    }
    gzclose($fp);
}

我已经对此进行了测试,效果很好。

答案 2 :(得分:1)

您可以通过编写自己的stream handler来拦截对基础文件的写入。

修改:在此页面上阅读规范example 3后,您可能会感兴趣

答案 3 :(得分:1)

不要忘记,您可以在不使用csv功能的情况下手动执行此操作,而无需再进行任何工作。我最近必须这样做,所以我可以获取相同的数据,并输出CSV作为制表符分隔符,逗号分隔符或浏览器可以显示的内容。

你需要做的就是使用基本数组和内爆(这里是一个基本的例子,你需要添加一些vars来支持正确的HTMl表输出,例如列的头部和尾部,行头和尾部等......但是你得到这个想法:

switch ( $_GET['mode'] )
{
    case "csv":
        $wrapper = "'";
        $delimiter = ",";
        $nextrow = "\n";
        break;
    case "txt":
        $wrapper = "";
        $delimiter = "\t";
        $nextrow = "\n";
        break;
    case "html":
        $wrapper = "'";
        $delimiter = ",";
        break;
}

$output = array();
$sql = "SELECT * FROM table";
$result = mysql_query($sql);
while ( $row = mysql_fetch_assoc($result) )
{
    $line = array();
    foreach ( $row as $column => $value )
    {
        $line[] = $wrapper . $value . $wrapper;
    }
    $output[] = implode("", $line) . $nextrow;
}

print implode("",$output);