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


Is there a limit to the amount of data that can be passed on to the special output stream php://output?

我目前正在测试通过网络应用程序生成的报告的新导出为 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只是这里看到的形式多维数组。

该代码非常适合小型数据集,例如 100 行及以下(不幸的是,不太确定截止点在哪里)。使用更大的数据集;但是,当我尝试导出为 CSV 时,浏览器不会显示"文件打开/保存"对话框,而是在网页上显示原始报告内容。

我用Firefox的"Live HTTP Headers"插件检查了HTTP标头,发现对于较大的数据集,标头设置不正确,显示为"text/html; charset=utf-8"而不是"application/vnd.ms-excel"。很奇怪。

奇数

:您可能想尝试定期刷新输出缓冲区。我发现我需要这样做以防止类似的错误。大致如下:

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

其中$len是行数。把它放进你的array_walk很混乱,但这可能会有所帮助。

我相信

我已经找到了一个可能的解决方案。不完全确定它为什么有效;但它确实如此。我只是在调用 clearHttpHeaders 之前添加了以下内容:

ob_start('ob_gzhandler');

像魅力一样工作。