我一直在开发一个基于 Web 的应用程序,通过 PHP 导出数据库信息。应用程序的原始版本最初生成了一个 OpenXML 工作表,但遇到了一个问题,即超出一定行数(大约 9500 行),生成的工作表太大而无法导入到 Excel 或 OpenOffice 中。
随后,我重新设计了应用程序以使用 libxl 的 php_excel 包装器,它在测试中工作得很好,但是当部署到实时服务器(与测试服务器相比,实时服务器的数据量更大)时,进程的内存使用量将达到 2GB 以下一点,然后失败,给出此错误:
Call to a member function write() on a non-object in...etc etc.
现在,有趣的是代码适用于较小的数据集,如果我限制请求的数据量,我可以从数据库中收集部分数据转储。从所有调查来看,当代码尝试引用未分配的对象时,会发生此错误。下面是代码:
$objPHPExcel = new ExcelBook($rcn, $rcl, true);
for ($i=0;$i<$myCCount;$i++){
$myPCount = count($mySelection[$i])
for ($j=1;$j<$myPCount;$j++){
$myWorkSheet = $myAccountSelection[$i][0] . ' - ' . $myAccountSelection[$i][$j];
$thisSheet = $objPHPExcel->addSheet($myWorkSheet);
for ($k=0;$k<count($myQueryArray);$k++){
$thisSheet->write(0, $k, $titleList[$myQueryArray[$k]]); //Error on this line
}
//The rest is database queries and spreadsheet generation.
再次,我想重申,这适用于较小的数据集(相同数量的行,更少的列,或相同数量的列,但更少的行),并且在出错之前将运行大约十五分钟。
根据要求,完整数据转储最多将生成 924 个工作簿(减去没有实际条目的工作簿),每个工作簿中的 ~360 列包含总共 10,000+ 行。
谁能帮我确定在这种情况下的实际问题是什么?
编辑更新:经过一些记录和挖掘php_excel包装器的错误处理(例如它),我确定问题确实是遇到了内存分配限制 - 在包装器本身内。在这种情况下,PHP或FastCGI或机器其余部分可用的可用内存量无关紧要,因为一旦达到一定数量(我目前正在尝试确定限制的确切内容)。除非有人能教我一种提高phpexcel包装器可以处理的单元格数量的方法,否则我认为这是一个"无法解决但已知的问题"。
在某些情况下,此行中的代码:
$thisSheet = $objPHPExcel->addSheet($myWorkSheet);
$thisSheet
将为空,
将以下代码更改为:
if ($thisSheet) {
for ($k=0;$k<count($myQueryArray);$k++){
$thisSheet->write(0, $k, $titleList[$myQueryArray[$k]]); //Error on this line
}
}
以避免错误。
$objPHPExcel->addSheet
reutuns null 的原因可能是内存使用量达到限制,您可以使用 ini_set("memory_limit", -1);
将内存使用量设置为无限制。