1

我遇到过几次这个问题。

我有一段将数据导出到 CSV 的代码。我使用的方法将结果集传递给模板,模板循环遍历结果,回显字段。

在行动中:

$this->result = ObjectPeer::doSelect($criteria);

在模板中:

foreach ($result as $row)
{
  echo $row->getValue1().','.$row->getValue2().','.$row->getValue3()...
}

但是,如果结果集很大,我会用完内存:

 [error] PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 1556481 bytes) in exportSuccess.php on line 13, referer: https://mysite.com/module

该过程使用了超过 250 mb,但它创建的文件只有 ~2 mb。我可以增加 php.ini 为进程提供的内存量,但我宁愿不这样做。如果导出足够大,我有点怀疑我能否给它足够的内存。

我读过一些与此类似的其他案例,这些案例建议在每次回显后取消设置 $row。这在我的情况下不起作用。

我认为有一种方法可以将这个查询分块并仍然构建整个文件 - 任何人都可以推荐或指向一个清晰的教程吗?

4

2 回答 2

1

根据您要检索的元素数量(即:getValue1、、getValue2等..),您可以以不同的方式对结果进行水合:

$stmt = ObjectPeer::doSelectStmt($m_criteria);
while ($row = $stmt->fetch(PDO::FETCH_NUM))
{
  echo $row[0];
}

此外,您可以使用以下方法检查另一个解决方案doSelectRS

$rs = ObjectPeer::doSelectRS($criteria);
$rs->setFetchMode(ResultSet::FETCHMODE_ASSOC);

while($rs->next())
{
  $records = $rs->getRow();
  // then use $records['key'] to retrieve information
}

您可以检查的其他内容很少。这篇关于Propel 内存泄漏的法语文章。

于 2012-06-08T20:27:48.007 回答
-1

这是写入 csv 文件的基本思路。这不会显示与数据库的连接,但它是之后的一切,并确保在最后关闭连接。

$filename = 'c:\whatever.csv';

$fp = fopen($filename, "w")  or die(mysql_error());
echo "Connected to ".$filename." <br>";


$res = mysql_query("SELECT *
FROM $table1 

WHERE Something
");

// fetch a row and write the column names out to the file
echo mysql_error();
$row = mysql_fetch_assoc($res);
$line = "";
$comma = "";
foreach($row as $name => $value) {
$line .= $comma . '"' . str_replace('"', '""', $name) . '"';
$comma = ",";
}
$line .= "\n";
fputs($fp, $line);

// remove the result pointer back to the start
mysql_data_seek($res, 0);

// and loop through the actual data
echo mysql_error();
while($row = mysql_fetch_assoc($res)) {

$line = "";
$comma = "";
foreach($row as $value) {
    $line .= $comma . '"' . str_replace('"', '""', $value) . '"';
    $comma = ",";

}
$line .= "\n";
fputs($fp, $line);
}
于 2012-06-08T18:41:58.397 回答