Я использую библиотеку PHPExcel для чтения файлов xls и xlsx. Ниже приведен пример функции для демонстрации проблемы, что у меня есть:PHPExcel - утечка памяти при прохождении всех строк
public function memoryAction()
{
$filename = "example.xlsx";
echo "<br>Script started<br>";
echo memory_get_usage(true);
$inputFileType = PHPExcel_IOFactory::identify($filename);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setReadDataOnly(true);
$objReader->setLoadSheetsOnly(array('OTMS','Printing'));
$excelReader = $objReader->load($filename);
echo "<br>Reader Initiliazed<br>";
echo memory_get_usage(true);
foreach ($excelReader->setActiveSheetIndex(0)->getRowIterator() as $row) {
if ($row->getRowIndex() == 1) {
continue;
}
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
$excelRow = array();
foreach ($cellIterator as $cell) {
$columnIndex = $cell->getColumn();
$cellValue = $cell->getCalculatedValue();
$excelRow[$columnIndex] = $cellValue;
}
if (empty($excelRow)) {
continue;
}
echo "<br>Row ".$row->getRowIndex()."<br>";
echo memory_get_usage(true);
}
echo "<br>Went through each row<br>";
echo memory_get_usage(true);
die();
}
Таким образом, в основном я иду через каждую строку в таблице и выходной памяти использования Excel. Дело в том, что использование памяти увеличивается после каждых 20-30 строк.
Вот значения, которые я получаю:
Сценарий начал 1835008 -1,75 Mb
Считыватель инициализирован 19660800 - 18,75 Mb
Пошел через каждую строку 47972352 - 45,75 Mb
Я прочитал несколько сообщений в Интернете о проблеме памяти PHPExcel. Да, он потребляет много памяти. Вы можете видеть, что я использую функцию setReadDataOnly() и что я загрузил только конкретные рабочие листы. Но я до сих пор не понимаю, почему просто цикл по рядам потребляет память.
Есть ли способ отключить объекты строки/ячейки в цикле и освободить память? Цените любую помощь.
UPD
Я запустить код Марка и вот результат для моего файла:
Base Memory: 1835008
Reader Initialised/File Loaded
19660800
Row 256 memory usage: 24903680
Row 512 memory usage: 33030144
Row 768 memory usage: 38797312
Went through each row
Final memory usage: 48234496
Я использую PHPExcel версии 1.7.8. и PHP 5.5.11. Вероятно, стоит обновить библиотеку PHPExcel.
UPD 2
Я установил версию 1.8.0 библиотеки PHPExcel. Реализованные проекты:
Base Memory: 1835008
Reader Initialised/File Loaded
15990784
Row 256 memory usage: 20185088
Row 512 memory usage: 27262976
Row 768 memory usage: 31719424
Went through each row
Final memory usage: 40108032
Любые идеи, почему это происходит? Я использую Zend Framework и называю этот код в контроллере действий. Тестовый файл содержит 4 вкладки, размер файла - 619 КБ. Код работает только с первой вкладкой, которая содержит 1000 строк.
Это фактический код, который вы используете для тестирования использования памяти? Потому что вы должны отображать память после итерации по столбцам в каждой строке, и это не отображается в вопросе. Я вижу, что вы создаете массив ячеек из каждой строки ('$ excelRow [$ columnIndex] = $ cellValue;': вы на самом деле строите массив строк? Это поднимает вопрос о том, почему вы чувствуете необходимость сначала создайте массив, а во-вторых, почему вы не используете встроенные методы PHPExcel, чтобы сделать это для вас. –
Простое переключение по строкам не требует дополнительной памяти в PHPExcel –
@MarkBaker да, это фактический код, который Я использую для тестирования. Я не добавлял информацию об использовании памяти после каждой итерации, потому что в выводе много строк. Я создаю массив ячеек, потому что в конце концов я передам данные каждой строки в другую функцию для обработки. – Tamara