致命错误:当内存使用率非常高时,调用非对象上的成员函数 write()
Posted
技术标签:
【中文标题】致命错误:当内存使用率非常高时,调用非对象上的成员函数 write()【英文标题】:Fatal Error: Call to a member function write() on a non-object occurs when memory usage is very high 【发布时间】:2013-11-25 13:00:08 【问题描述】:我一直在开发一个基于 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.
我想再次重申,这适用于较小的数据集(行数相同但列数更少,或列数相同但行数更少),并且会运行大约 15 分钟,然后才会出错。
根据要求,完整的数据转储将生成最多 924 个工作簿(减去没有实际条目的工作簿),每个工作簿中的大约 360 列包含总计 10,000 多行。
谁能帮我确定在这种情况下到底是什么问题?
编辑更新: 在对 php_excel 包装器的错误处理(例如)进行了一些记录和挖掘之后,我确定问题确实是在包装器本身内遇到了内存分配限制。在这种情况下,PHP 或 FastCGI 或机器其余部分可用的可用内存量无关紧要,因为一旦达到一定量(我目前正在尝试确定限制是多少) )。除非有人可以教我如何提高 phpexcel 包装器可以处理的单元格数量,否则我认为这是一个“无法解决但已知的问题”。
【问题讨论】:
错误到底发生在哪里? @Pekka웃 我会在第二个代码 sn-p 中的第 8 行说(这里写着//Error on this line
)
那么很可能$objPHPExcel->addSheet
没有返回对象。 PHPExcel 是否有某种错误处理?那将是查看问题所在的最佳位置
这种类型的问题伴随着批量数据。我也遇到过这个问题。我使用以下设置来克服这个问题 ini_set( 'max_execution_time', 0 );: ini_set( 'memory_limit', -1 );我认为这在这种情况下会起作用。
不幸的是,这不起作用。我的内存限制一开始就设置得非常高(设置为最多允许 3GB),并且我在使用的内存低于 2GB 时收到了错误。我确实尝试过使用无限内存并取消执行时间限制,但我开始认为这是 php_excel 包装器的问题。
【参考方案1】:
在某些情况下,这行代码:
$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);
将内存使用设置为无限。
【讨论】:
同意问题所在,但如果是内存限制问题,脚本会崩溃 不幸的是,这不是内存使用限制问题 - 见上文。即使在将内存使用设置为无限之前,可用内存也远远超过出现错误时正在使用的内存。不幸的是,问题似乎出现在 php_excel 包装器中。 我使用的是 PHP 5.5,在内存负载下运行时随机看到这些错误。以上是关于致命错误:当内存使用率非常高时,调用非对象上的成员函数 write()的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:对 SQL SERVER 2012 的非对象 XAMPP 上的成员函数 query() 调用
致命错误:在非对象上调用成员函数 getLoginUrl()
致命错误:调用非对象代码点火器 $query->num_rows()==1) 上的成员函数 where() [重复]