致命错误:当内存使用率非常高时,调用一个非对象的成员函数write()

我一直在研究一个基于Web的应用程序来通过PHP导出数据库信息。 原始版本的应用程序最初生成了一个OpenXML工作表,但遇到超出特定行数(大约9500)的问题,生成的工作表太大而无法导入到Excel或OpenOffice中。

我随后重新编写了这个应用程序来使用libxl的php_excel包装器,这个包装器可以在testing中正常工作,但是当部署到活动服务器(与testing服务器相比数据量更大)时,这个过程的内存使用量将会达到只是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. 

再一次,我想重申,这适用于较小的数据集(相同数量的行较less的列,或相同的列数,但较less的行),并将运行大约十五分钟才出错。

根据要求,完整的数据转储最多可以生成924个工作簿(减去没有实际条目的工作簿),在每个工作簿中包含约360列,总共包含10,000个以上的行。

任何人都可以帮助我确定在这种情况下实际上是什么问题?

编辑更新:经过一些日志logging和挖掘通过php_excel包装的error handling(如是),我已经确定,问题确实是一个内存分配限制正在命中 – 在包装本身。 在这种情况下,可用于PHP或FastCGI或机器其余部分的可用内存量并不重要,因为一旦它达到一定数量(我正在尝试精确限制哪些限制)。 除非任何人能教育我提高phpexcel包装纸可以处理的细胞数量,否则我认为这是一个“无法解决但已知的问题”。

在某些情况下,这行代码:

 $thisSheet = $objPHPExcel->addSheet($myWorkSheet); 

$thisSheet将为null,

将以下代码更改为:

 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); 将内存使用设置为无限制。