允许的内存大小为134217728字节,在PhpExcel中耗尽

允许的内存大小为134217728字节,在PhpExcel中耗尽,php,phpexcel,php-extension,Php,Phpexcel,Php Extension,我使用phpexcel导出文件xlsx,数据有32列和许多行。每天数据都在增加,所以数据会非常大。这是我的代码: $filename="data.xlsx"; $cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; $cacheSettings = array( 'memoryCacheSize' => '128MB'); PHPEx

我使用phpexcel导出文件xlsx,数据有32列和许多行。每天数据都在增加,所以数据会非常大。这是我的代码:

$filename="data.xlsx";
            $cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
            $cacheSettings = array( 'memoryCacheSize' => '128MB');
            PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
            ini_set('max_execution_time', 123456);
            $objPHPExcel = new PHPExcel();
            $objPHPExcel->setActiveSheetIndex(0);
            $i = 2;
            $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Header1');
            $objPHPExcel->getActiveSheet()->setCellValue('B1', 'Header2');
            $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Header3');
            $objPHPExcel->getActiveSheet()->setCellValue('D1', 'Header4');
            $objPHPExcel->getActiveSheet()->setCellValue('E1', 'Header5');
            $objPHPExcel->getActiveSheet()->setCellValue('F1', 'Header6');
            $objPHPExcel->getActiveSheet()->setCellValue('G1', 'Header7');
            $objPHPExcel->getActiveSheet()->setCellValue('H1', 'Header8');
            $objPHPExcel->getActiveSheet()->setCellValue('I1', 'Header9');
            $objPHPExcel->getActiveSheet()->setCellValue('J1', 'Header10');
            $objPHPExcel->getActiveSheet()->setCellValue('K1', 'Header11');
            $objPHPExcel->getActiveSheet()->setCellValue('L1', 'Header12');
            $objPHPExcel->getActiveSheet()->setCellValue('M1', 'Header13');
            $objPHPExcel->getActiveSheet()->setCellValue('N1', 'Header14');
            $objPHPExcel->getActiveSheet()->setCellValue('O1', 'Header15');
            $objPHPExcel->getActiveSheet()->setCellValue('P1', 'Header16');
            $objPHPExcel->getActiveSheet()->setCellValue('Q1', 'Header17');
            $objPHPExcel->getActiveSheet()->setCellValue('R1', 'Header18');
            $objPHPExcel->getActiveSheet()->setCellValue('S1', 'Header19');
            $objPHPExcel->getActiveSheet()->setCellValue('T1', 'Header20');
            $objPHPExcel->getActiveSheet()->setCellValue('U1', 'Header21');
            $objPHPExcel->getActiveSheet()->setCellValue('V1', 'Header22');
            $objPHPExcel->getActiveSheet()->setCellValue('W1', 'Header23');
            $objPHPExcel->getActiveSheet()->setCellValue('X1', 'Header24');
            $objPHPExcel->getActiveSheet()->setCellValue('Y1', 'Header25');
            $objPHPExcel->getActiveSheet()->setCellValue('Z1', 'Header26');
            $objPHPExcel->getActiveSheet()->setCellValue('AA1', 'Header27');
            $objPHPExcel->getActiveSheet()->setCellValue('AB1', 'Header28');
            $objPHPExcel->getActiveSheet()->setCellValue('AC1', 'Header29');
            $objPHPExcel->getActiveSheet()->setCellValue('AD1', 'Header30');
            $objPHPExcel->getActiveSheet()->setCellValue('AE1', 'Header31');
            $objPHPExcel->getActiveSheet()->setCellValue('AF1', 'Header32');
            foreach ($data as $value) {
                $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $value['1']);
                $objPHPExcel->getActiveSheet()->setCellValue('B'.$i, $value['2']);
                $objPHPExcel->getActiveSheet()->setCellValue('C'.$i, $value['3']);
                $objPHPExcel->getActiveSheet()->setCellValue('D'.$i, $value['4']);
                $objPHPExcel->getActiveSheet()->setCellValue('E'.$i, $value['5']);
                $objPHPExcel->getActiveSheet()->setCellValue('F'.$i, $value['6']);
                $objPHPExcel->getActiveSheet()->setCellValue('G'.$i, $value['7']);
                $objPHPExcel->getActiveSheet()->setCellValue('H'.$i, $value['8']);
                $objPHPExcel->getActiveSheet()->setCellValue('I'.$i, $value['9']);
                $objPHPExcel->getActiveSheet()->setCellValue('J'.$i, $value['10']);
                $objPHPExcel->getActiveSheet()->setCellValue('K'.$i, $value['11']);
                $objPHPExcel->getActiveSheet()->setCellValue('L'.$i, $value['12']);
                $objPHPExcel->getActiveSheet()->setCellValue('M'.$i, $value['13']);
                $objPHPExcel->getActiveSheet()->setCellValue('N'.$i, $value['14']);
                $objPHPExcel->getActiveSheet()->setCellValue('O'.$i, $value['15']);
                $objPHPExcel->getActiveSheet()->setCellValue('P'.$i, $value['16']);
                $objPHPExcel->getActiveSheet()->setCellValue('Q'.$i, $value['17');
                $objPHPExcel->getActiveSheet()->setCellValue('R'.$i, $value['18']);
                $objPHPExcel->getActiveSheet()->setCellValue('S'.$i, $value['19']);
                $objPHPExcel->getActiveSheet()->setCellValue('T'.$i, $value['20']);
                $objPHPExcel->getActiveSheet()->setCellValue('U'.$i, $value['21']);
                $objPHPExcel->getActiveSheet()->setCellValue('V'.$i, $value['22']);
                $objPHPExcel->getActiveSheet()->setCellValue('W'.$i, $value['23']);
                $objPHPExcel->getActiveSheet()->setCellValue('X'.$i, $value['24']);
                $objPHPExcel->getActiveSheet()->setCellValue('Y'.$i, $value['25']);
                $objPHPExcel->getActiveSheet()->setCellValue('Z'.$i, $value['26']);
                $objPHPExcel->getActiveSheet()->setCellValue('AA'.$i, $value['27']);
                $objPHPExcel->getActiveSheet()->setCellValue('AB'.$i, $value['28']);
                $objPHPExcel->getActiveSheet()->setCellValue('AC'.$i, $value['29']);
                $objPHPExcel->getActiveSheet()->setCellValue('AD'.$i, $value['30']);
                $objPHPExcel->getActiveSheet()->setCellValue('AE'.$i, $value['31']);
                $objPHPExcel->getActiveSheet()->setCellValue('AF'.$i, $value['32']);
                $i++;
            }
            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
            ob_end_clean();
            header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            header("Content-Disposition: attachment; filename=".$filename);
            header('Cache-Control: max-age=0');
            $objWriter->setUseDiskCaching(true);
            $objWriter->save("php://output");
两天前,它运行良好。但今天,它抛出了一个例外:
致命错误:第155行的/…/Classes/PHPExcel/CachedObjectStorage/CacheBase.php中允许的内存大小为134217728字节(试图分配85字节)

请记住,除了PHPExcel对象使用的内存之外,php还使用内存和脚本本身


如果使用memoryCacheSize将cache\u设置为\phpTemp,phpexel对象将使用该限制的内存,然后切换到使用临时文件。memoryCacheSize与绝对php.ini内存限制(128MB)相同,因此在达到php自身的限制之前,PHPExcel将永远不会切换到使用临时文件单元缓存。尝试设置一个较低的memoryCacheSize(例如64MB),这样至少PHPExcel将有机会缓存单元格并减少其自身的内存使用。

请记住,除了PHPExcel对象使用的内存之外,PHP还使用内存以及脚本本身


如果使用memoryCacheSize将cache\u设置为\phpTemp,phpexel对象将使用该限制的内存,然后切换到使用临时文件。memoryCacheSize与绝对php.ini内存限制(128MB)相同,因此在达到php自身的限制之前,PHPExcel将永远不会切换到使用临时文件单元缓存。尝试设置一个较低的memoryCacheSize(例如64MB),这样至少PHPExcel将有机会缓存单元并减少其自身的内存使用。

另一点需要注意的是,您正在通过循环一个名为$data的数组来构建PHPExcel对象。。。。我猜,2d数组是通过循环数据库查询的结果构建的

这个$data数组也将占用您的大部分内存,随着结果数量的增加,每天的内存越来越多


如果您不通过循环数据库结果集来构建一个大数组,然后通过该数组来构建PHPExcel数据,而是通过循环数据库结果集直接构建PHPExcel数据,则效率会更高。这消除了$data的内存开销,并将2个循环减少到1个。

另一点需要注意的是,您正在通过循环一个名为$data的数组来构建PHPExcel对象。。。。我猜,2d数组是通过循环数据库查询的结果构建的

这个$data数组也将占用您的大部分内存,随着结果数量的增加,每天的内存越来越多



如果您不通过循环数据库结果集来构建一个大数组,然后通过该数组来构建PHPExcel数据,而是通过循环数据库结果集直接构建PHPExcel数据,则效率会更高。这消除了$data的内存开销,并将2个循环减少到1个。

哦,我尝试将momoryCacheSize设置为8Mb或64Mb,但仍然错误您尝试过其他任何缓存方法吗?除了SQLite之外,它们都维护一个“内存中的单元索引”,因此它们不消除内存使用,而只是减少内存使用。有些缓存比其他缓存更高效,但通常在内存和速度之间存在折衷。我还没有尝试过其他缓存方法,因为我不知道其他缓存方法。这就是阅读文档有帮助的地方。。。。开发人员文档中有一整节列出了不同的缓存方法以及如何使用。哦,我尝试将momoryCacheSize设置为8Mb或64Mb以下,但仍然存在错误。您尝试过其他缓存方法吗?除了SQLite之外,它们都维护一个“内存中的单元索引”,因此它们不消除内存使用,而只是减少内存使用。有些缓存比其他缓存更高效,但通常在内存和速度之间存在折衷。我还没有尝试过其他缓存方法,因为我不知道其他缓存方法。这就是阅读文档有帮助的地方。。。。开发人员文档中有一整节列出了不同的缓存方法以及如何使用它们,因为您根本没有使用Excel的任何功能,为什么不简单地编写一个csv文件呢?哦,我认为导出文件csv实际上很简单,因此,我想尝试使用文件excel,但我遇到了问题。当内存不足时,PHPExcel无法创建内存,它所能做的最好的事情是通过单元缓存减少内存占用(以牺牲执行速度为代价)。我估计每个单元的内存使用量约为1k,当您需要编写工作簿时,它会翻一番。单元缓存有助于减少1k/单元,但将来可能仍需要增加PHPA的可用内存。实际上,您根本没有使用Excel的任何功能,为什么不简单地编写一个csv文件呢?哦,我认为导出文件csv其实很简单,因此,我想尝试使用文件excel,但我遇到了问题。当内存不足时,PHPExcel无法创建内存,它所能做的最好的事情是通过单元缓存减少内存占用(以牺牲执行速度为代价)。我估计每个单元的内存使用量约为1k,当您需要编写工作簿时,它会翻一番。单元缓存有助于减少1k/单元,但可能会有一段时间需要增加可用内存,以满足PHPIt的伟大想法,我已经做到了。但在未来,如果数据增加超过100000或10000000行,那么解决内存泄漏的方法是什么?你不能完全消除内存使用,更多的行将增加所需的内存;虽然我建议使用SQLite缓存,它根本不需要在内存中维护任何单元格索引。。。但您肯定需要在某个时候增加PHP内存限制。。。。单元缓存允许您将一夸脱压缩到一品脱罐中,但不会将一加仑压缩到一品脱罐中。如果这是通过web请求生成的,您可能还需要将其切换到b