Как исправить память, израсходованную с помощью PHPExcel?
Неустранимая ошибка: допустимый размер памяти 134217728 байт исчерпан (пытался выделить 1078799 байт) в D:\xampplite\HTDOCS\Скребок\PHPExcel\чтения\Excel2007.php on line 269
Мой предел памяти 128M PHP быстро исчерпывается, даже когда я только пытаюсь открыть небольшой файл excel ~ 350 КБ с помощью PHPExcel.
Хотя, я могу увеличить ограничение памяти в конфигурации, но будет здорово увидеть, есть ли какие-либо альтернативы для исправления этого.
Ответы
Ответ 1
Размер файла не является хорошей мерой для файлов книг при работе с PHPExcel. Число строк и столбцов (т.е. ячеек) более важно.
Сам код PHPExcel имеет размер от 10 до 25 МБ, в зависимости от того, к каким компонентам обращаются.
В настоящее время каждая ячейка в рабочей книге занимает в среднем 1 тыс. памяти (без кэширования) или 1,6 тыс. на 64-битном PHP - я буду предполагать 32-битный PHP на данный момент - так (например) рабочий лист из 8000 линий с 31 столбцом (248 000 ячеек) будет составлять около 242 МБ. С кэшированием ячеек (например, php://temp или DiskISAM), которые могут быть уменьшены примерно до трети, поэтому для 8000 строк по 31 столбцам потребуется около 80 МБ.
Существует ряд опций, которые помогут вам уменьшить использование памяти:
Используете ли вы кеширование ячеек с помощью PHPExcel?
require_once './Classes/PHPExcel.php';
$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
$cacheSettings = array( ' memoryCacheSize ' => '8MB');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load("test.xlsx");
Если вам нужно только получить доступ к данным на ваших листах и не нуждаться в доступе к форматированию ячейки, вы можете отключить чтение информации форматирования из книги:
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx");
Если вам нужно только получить доступ к некоторым, но не ко всем листам в книге, вы можете загрузить только те рабочие листы:
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setLoadSheetsOnly( array("Worksheet1", "Worksheet2") );
$objPHPExcel = $objReader->load("test.xlsx");
если вы хотите читать только определенные ячейки в листах, вы можете добавить фильтр:
class MyReadFilter implements PHPExcel_Reader_IReadFilter
{
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadFilter( new MyReadFilter() );
$objPHPExcel = $objReader->load("test.xlsx");
Все эти методы могут значительно снизить требования к памяти.
Ответ 2
Просто потому, что файл данных - это только X байтов, не означает, что он использует X байтов RAM. Например, только 4K данных в массиве $_SESSION использует 64K RAM при загрузке. Это просто зависит от того, что делает код с этими данными. Правильный ответ заключается в увеличении количества бара.
Также, если это файл XLSX, это ZIP-документы XML. Текстовые файлы zip up намного жестче, чем 1/2, поэтому ваш файл 350K XLSX легко представляет собой файл Excel 1MB.
Ответ 3
PHPExcel известен утечками памяти. Я советую вам использовать следующее: ФРАКЦИЯ памяти, используемой PHPExcel.:
1) Для чтения: PHP-Excel-Reader
2) Для написания: Pear Spreadsheet Excel Writer
Ответ 4
Если вы хотите узнать, вы можете использовать xhprof. Согласно этой ссылке вы можете отслеживать использование памяти с ней...
Ответ 5
Xdebug является профилировщиком/отладчиком для php и может помочь вам отслеживать использование памяти и функциональные вызовы, чтобы выяснить, в чем проблема. И его легко установить, большинство дистрибутивов Linux имеют его в репозитории, "yum install xdebug", "apt-get install xdebug".
Ответ 6
Одной вещью, которую вы должны заметить, также являются пустые ячейки.
У меня была такая же проблема, только 800 строк данных и script были даже не в состоянии читать.
Как таймауты, так и ошибки в памяти, если они были исправлены.
Что-то @Mark Бейкер сказал, что клетки заставляют меня думать. Я заметил, что у меня было множество пустых ячеек и копирование только ячеек с данными в новую книгу заставил его запустить за секунду.
Надеюсь, это поможет кому-то.
Ответ 7
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx");
Этот много кода достаточно
Ответ 8
В этом сообщении говорится о том, как закрыть PHPExcel-ридер:
Как закрыть файл excel в php-excel-reader
Если вы одновременно открываете несколько файлов Excel, но на самом деле им не нужны все одновременно, вы можете попытаться открыть и закрыть (то есть отключить) считыватели для каждого файла один за другим. Btw, используя одно и то же имя переменной для читателей, было бы достаточно для операции "сбрасывания".