可以传递给特殊输出流php:// output的数据量是否有限制?

时间:2012-04-19 14:37:23

标签: php csv symfony1 http-headers

我目前正在为通过webapp生成的报告测试新的CSV导出功能。因此相关代码如下:

$my_report_data = ReportDAO::runCampaignAnalysis($campaign_id, $start_date, $end_date);

$this->getResponse()->clearHttpHeaders();
$this->getResponse()->setHttpHeader('Content-Type', 'application/vnd.ms-excel');
$this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename='export.csv');

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

function __outputCSV(&$vals, $key, $filehandler) {
     $retval = fputcsv($filehandler, $tempArray);
     if($retval == FALSE) {
         error_log('Uh oh, spaghetti o!');
         error_log('The current line being processed is: ' . join('|', $vals));
     }
 }

 array_walk($my_report_data, "__outputCSV", $outstream);
 fclose($outstream);

 return sfView::HEADER_ONLY;

$ my_report_data只是seen here形式的多维数组。

该代码与小型数据集完美配合,例如100行及以下(不太确定切断位置不幸)。使用更大的数据集;但是,当我尝试导出到CSV时,浏览器不会显示文件打开/保存对话框,而是在网页上显示原始报告内容。

我已经使用Firefox的“Live HTTP Headers”插件检查了HTTP标头,发现对于较大的数据集,标题设置不正确并显示为'text / html; charset = utf-8'而不是'application / vnd.ms-excel'。非常离奇。

2 个答案:

答案 0 :(得分:1)

奇怪:你可能想尝试定期刷新输出缓冲区。我发现我需要这样做以防止类似的错误。有点像:

if($len > 250){ $len = 0; if(ob_get_length()) ob_flush(); }

其中$len是一个行数。凌乱,以适应你的array_walk,但这可能会有所帮助。

答案 1 :(得分:0)

我相信我找到了一个可能的解决方案。不完全确定它的工作原理;但确实如此。我只是在调用clearHttpHeaders之前添加了以下内容:

ob_start('ob_gzhandler');

像魅力一样工作。