我们遇到了一个奇怪的问题。它是这样的。我们需要输出大量数据到客户端。这些数据文件无法预先构建,必须通过实时数据提供。
我首选的解决方案是从这样的提取中逐行写入CSV:
while($datum = $data->fetch(PDO::FETCH_ASSOC)) {
$size += fputcsv($outstream, $datum, chr(9), chr(0));
}
这绕过了很多荒谬的内存使用(一次读取内存中的100000条记录是坏事)但是我们仍然会遇到大型表格的问题,这些问题只会随着数据量的增加而变得更糟。请注意,没有数据分区;他们不会在年度段中下载,但他们会下载所有数据,然后自行分段。这符合要求;我无法改变这一点,因为它完全消除了这个问题。
在任何一种情况下,在最大的表上都会耗尽内存。一种解决方案是增加可用内存,这解决了一个问题,但建议稍后或甚至现在如果下载多个客户端时出现服务器负载问题。
在这种情况下,$ outstream是:
$outstream = fopen("php://output",'w');
这显然不是真正的物理磁盘位置。我不太了解php://输出数据在发送到客户端之前的位置,但很明显,通过这种方法简单地将流形数据库表写入csv存在内存问题。
确切地说,staging框允许大约128mb用于PHP,并且这个调用特别短约40mb(它试图分配40mb以上。)这似乎有点奇怪的行为,正如你所期望的那样要求内存较小的部分。
任何人都知道可以采取哪些措施来解决这个问题?
答案 0 :(得分:2)
因此看起来内存消耗是由Zend Framework的输出缓冲引起的。我想出的最好的解决方案就是这个。
在我们开始将文件流式传输到客户端之前执行ob_end_clean()。 ZF的这个特定实例不会产生任何正常输出或在此之后做更多的事情,因此不会出现并发症。发生了什么奇怪的事情(也许是从用户的角度来看)是他们真正将文件传输给他们。
以下是代码:
ob_end_clean();
while($datum = $data->fetch(PDO::FETCH_ASSOC)) {
$size += fputcsv($outstream, $datum, chr(9), chr(0));
}
内存使用情况(根据某个ZF论坛帖子中建议的函数memory_get_peak_usage(true))从90兆字节下降到9兆字节,这是在任何文件读取之前我在开发框中使用的内容。
感谢您的帮助,伙计们!