我正在将数据从 MySQL 数据库表导出到 Excel 文件。但是导出大量数据显示内存限制错误。
我已将我的php.ini
文件中的内存限制设置为 1024M,并且它现在工作正常,因为它现在有 300,000 条记录/行。
但是这个计数会不断增长,所以我在我的 PHP 文件中使用了以下代码。但我不确定这样做是否正确。我希望它不会影响我的任何功能。
ini_set("memory_limit",-1);
这是我用来从 Excel 数据库导出数据的代码:
ini_set("memory_limit",-1);
if (isset($_POST["export"])) {
$query_discount = "SELECT * FROM tb_discount";
$productResult1 = mysql_query($query_discount, $con);
$filename_discount = "Discount_data_report.xls";
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"$filename_discount\"");
$isPrintHeader_discount = false;
if (! empty($productResult1)) {
while ($row_discount = mysql_fetch_assoc($productResult1)) {
if (! $isPrintHeader_discount) {
echo implode("\t", array_keys($row_discount)) . "\n";
$isPrintHeader_discount = true;
}
echo implode("\t", array_values($row_discount)) . "\n";
}
}
exit();
}
不要增加 PHP
memory_limit
,除非你真的必须并且只在需要该限制的代码部分或文件中这样做。一般来说,这完全取决于您的代码,并且 PHP 脚本不是内存消耗大户。
PHP 脚本仅在脚本运行时使用内存。因此,如果这是在 Apache 服务器上,如果您完全删除
memory_limit
块,那么任何使用您网站的人都可能通过向您的网站发送大量请求来对您的网站进行 DDoS 攻击,这些请求将任意填充您服务器上的 RAM,直到该网站无法使用。即使您是从命令行使用此脚本——这意味着您在需要时自己运行它——这也被认为是不好的做法。但是有一个可行的解决方案。
只需将该
ini_set("memory_limit",-1);
指令仅添加到绝对需要它的脚本或代码块中。因此,如果您的 Excel 导出代码在一个单独的特定文件中运行,只需将其添加
ini_set("memory_limit",-1);
到该文件即可。或者,如果您有更复杂的代码,Excel 导出是其中的一部分,最好将其放在仅ini_set("memory_limit",-1);
处理导出的代码区域中,而不要放在代码的其余部分中。所以你们有一个处理导出的函数或方法,只需将它
ini_set("memory_limit",-1);
放在那个函数或方法中。或者您有if
出口条件?然后将其放置ini_set("memory_limit",-1);
在if
条件区域中。归根结底,诸如此类的事情
memory_limit
是有原因的。他们不是你的敌人。始终以允许它们有限制的方式调整它们,并且只有在任务或条件绝对需要时才解除该限制。因此,对于您的示例代码,我建议从以下两行更改:
对此:
这样一来,您只有
memory_limit
在清楚明确地进行导出时才每次都取消限制。过去的任何一个……
您的代码存在明显的可扩展性问题。
重构您的代码,使其可以在不达到内存限制的情况下适当扩展。
在没有看到您的代码的情况下,您似乎只是在不使用
OFFSET
or进行全面的 MySQL 查询LIMIT
,这会导致您出现问题。相反,我会记录您重构代码以在 MySQL 代码中使用OFFSET
或使用LIMIT
,然后将结果附加到导出的 Excel 文件中。这将使您不必担心 PHP 内存限制并允许您更好地扩展代码。类似于
foreach
PHP 循环的东西,它在一组基础上调整OFFSET
orLIMIT
,比方说,每个循环 1,000 条记录,然后将数据附加到该 Excel 文件。这是更好、可扩展且更可靠的长期解决方案。