致命错误:当内存使用率非常高时,在非对象上调用成员函数 write() 时会发生


Fatal Error: Call to a member function write() on a non-object occurs when memory usage is very high

我一直在开发一个基于 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); 将内存使用量设置为无限制。