【问题标题】:How to free memory in PHP or improve PHPExcel?如何在 PHP 中释放内存或改进 PHPExcel?
【发布时间】:2016-03-13 12:28:45
【问题描述】:

PHPExcel 需要太多内存来加载文件。我想通过内存使用来改进这段代码。

在此代码上出现错误Fatal error: Allowed memory size of 536870912 bytes exhausted

/* class PHPExcel_Cell 
 *
 * $returnValue = array()
 * 
*/

$sortKeys = array();

foreach (array_unique($returnValue) as $coord) {
    sscanf($coord,'%[A-Z]%d', $column, $row);
        $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;
}

ksort($sortKeys);

return array_values($sortKeys);

$returnValue = array("B1", "C12", "C1", "D3", "B2"...)
必须像数组一样排序("B1", "B2", "C1", "C12")

第一个问题:如果我理解正确,array_unique使用一个额外的数组来存储结果,所以总内存使用x2(如果我们有具有唯一元素的数组)。但我认为不需要使用array_unique,因为任何重复都会用这一行重写:

$sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;

第二个问题:这段代码使用了两个数组:$returnValue 和 $sortKeys(2x 内存),所以我改写成这样:

$len = count($returnValue);

for ($i = 0; $i < $len; $i++) {

    $val = $returnValue[$i];
    unset($returnValue[$i]);

    sscanf($val,'%[A-Z]%d', $column, $row);
    $returnValue[sprintf('%3s%09d',$column,$row)] = $val;

}

ksort($returnValue);

return array_values($returnValue);

但是 unset() 不会释放内存,只会从数组中删除元素,并且 gc_collect_cycles() 也不起作用。

取消设置后如何释放内存?
也许您知道其他方式,如何通过内存使用来改进此代码?

附:我无法使用 xlsx2csv 和其他 bash 工具。

【问题讨论】:

  • 您可以尝试使用 Spout (github.com/box/spout)。它的功能比 PHPExcel 少,但在性能和内存使用方面非常出色(您不需要超过 10MB!)。
  • @Adrien - How to improve PHPExcel 并不意味着 how to switch to an alternative....运行 PHP
  • 我提到 Spout 是因为最初的问题已经提到了替代品 (xlsx2csv),所以我认为它是合适的。我在这里理解问题的方式不是关于如何改进 PHPExcel 的 gc,而是更多关于如何完成我的工作。如果您认为我的评论不合适,请随时删除我的评论,并请接受我的道歉:)

标签: php algorithm memory garbage-collection phpexcel


【解决方案1】:

我不确定它是否有帮助,但你可以试试这个:

$spreadsheet->disconnectWorksheets();
unset($spreadsheet);

来自:https://phpspreadsheet.readthedocs.io/en/latest/topics/creating-spreadsheet/#clearing-a-workbook-from-memory

【讨论】:

    【解决方案2】:

    您的代码看起来很奇怪,您从数组中删除元素,然后在一个循环中添加一个新元素。 当我使用 PHPExcel 时,我使用析构函数来释放内存并且效果很好

    function __destruct()
        {
            if ($this->phpExcelObj) {
                \PHPExcel_Calculation::unsetInstance($this->phpExcelObj);
                if ($this->phpExcelObj) {
                    $this->phpExcelObj->disconnectWorksheets();
                    unset($this->phpExcelObj);
                }
            }
        }
    

    另一种方法是使用 Word 制作模板并使用 PHPExcel 加载该模板,这样您就可以避免使用内存消耗操作来制作文档标记。 这些技术帮助我使用 PHPExcel 加载数百万行,但内存不多。

    【讨论】:

    • 它在第一次加载时中断,所以析构函数无能为力。
    猜你喜欢
    • 2018-01-26
    • 2011-11-03
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2011-12-08
    • 2012-01-18
    • 2023-04-05
    相关资源
    最近更新 更多