所以我希望能够通过一个简单的解决方案来读取数据库中的记录并将其保存到用户下载的文本文件中。我一直在做这个,不到20,000条记录,这很好用。超过20,000条记录,我将太多数据加载到内存中,PHP发生致命错误。
我的想法是抓住一切块。所以我抓住XX行并将它们回显到文件然后循环以获得下一个XX行直到我完成。
我现在只是回应结果,不是构建文件然后发送下载,我猜我不得不这样做。
此时的问题简洁,即最多20,000行,文件构建和下载完美。除此之外,我得到一个空文件。
代码:
header('Content-type: application/txt');
header('Content-Disposition: attachment; filename="export.'.$file_type.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
// I do other things to check for records before, hence the do-while loop
$this->items = $model->getItems();
do {
foreach ($this->items as $k => $item) {
$i=0;
$tables = count($this->data['column']);
foreach ($this->data['column'] as $table => $fields) {
$columns = count($fields);
$j = 0;
foreach ($fields as $field => $junk) {
if ($quote_output) {
echo '"'.ucwords(str_replace(array('"'), array('\"'), $item->$field)).'"';
} else {
echo ''.$item->$field.'';
}
$j++;
if ($j<$columns) {
echo $delim;
}
}
$i++;
if ($i<$tables) {
echo $delim;
}
}
echo "\n";
}
} while($this->items = $this->_model->getItems());
答案 0 :(得分:1)
非常大的表格无法正常工作。
您必须在从数据库中读取数据时输出数据。如果需要排序,请使用数据库ORDER BY来实现此目的。
所以或多或少
// assuming you use a var such as $query to handle the DB
while(!$query->eof())
{
$fields = $query->read_next();
echo $fields; // with your formatting, maybe call a function...
}
空结果正常。如果在发生任何回声之前内存耗尽,则没有任何内容发送到浏览器。
另请注意,PHP有一个您可能需要调整的时间限制(监视程序)。默认值在php.ini中定义。如果您希望表格增长很多,可以将其设置为零。
答案 1 :(得分:0)
您应该更改addslashes()
的str_replace。这可能会释放一些记忆。
然后我建议您保存文件并使用php文件函数执行此操作:fopen()
或file_put_contents()
。
我希望这可以帮到你!
答案 2 :(得分:0)
实际上,这可能是简单的修复。如果PHP内存不足,可能是因为在发送文件之前输出缓冲区正在填充。如果是这样,只需定期flush()
。
这将在每行之后刷新:
do {
foreach(...) {
// assemble your output line here
}
echo "\n";
flush();
}
} while($this->items = $this->_model->getItems());
在每一行之后冲洗可能会证明太慢,在这种情况下,每增加一个计数器并在每百次之后冲洗,或者任何最佳效果。