PHPExcel Memory Leak, so geht es noch am besten..
Erstellt von Arne | Erstellt in Software- & Webentwicklung | Am 04-09-2012
0
Vor ganz langer Zeit hatte ich ja mal bereits über die Verwendung von PHPExcel zum Erzeugen von Excel Dateien aus PHP geblogged.
Nun war es in der Firma mal wieder an der Zeit einen Export zu bauen, tja das Problem: 12.000 Zeilen und knapp 150 Spalten (-: Da hat dann der Arbeitsspeicher nicht mehr so mitgespielt wie wir das wollten. Zum Berechnen wie viel RAM ihr so braucht gilt folgende Rechnung: Anzahl der Zellen * 1 KiloByte.
Die bisher beste Lösung, in Hinsicht auf den Verbrauch von Arbeitsspeicher sieht jetzt so aus (nach einigen Experimenten):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// SQLiteCache hält die Cell-Data nicht im Speicher $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite; PHPExcel_Settings::setCacheStorageMethod($cacheMethod); // Benutze Zend Framework, alternativ hier dann die PDOMySQL Connection $db = Zend_Db_Table_Abstract::getDefaultAdapter(); // Das PHPExcel Objekt darf erst nach dem Setzen des Cahches erzeugt werde $phpExcel = new PHPExcel(); // einfach SQL Query $sql = 'SELECT * FROM IMPORT LIMIT 7000'; $stmt = $db->query($sql); $rowCNT = 1; // bei vielen Daten bitte kein fetchALL(); while($rows = $stmt->fetch()){ $phpExcel->getActiveSheet()->fromArray($rows, null, 'A'.$rowCNT); $rowCNT++; } // Aufräumen unset($rowCNT); unset($select); unset($db); // Speichern $phpExcelWrite = new PHPExcel_Writer_Excel2007($phpExcel); $phpExcelWrite->setUseDiskCaching(true); $phpExcelWrite->save(str_replace('.php', '.xls', __FILE__)); |
Was sind die Fallstricke beziehungsweise worauf achten?
- Nur die Caching-Methoden SQLITE/SQLITE3 schreiben nicht in den RAM
- Der Cache muss VOR dem Erzeugen des PHPExcel Objects gesetzt sein
- Vermeiden von fetchAll(), lieber die Zeilen einzeln aus der Datenbank besorgen
- Arbeitsspeicher erhöhen
- Werte in die Zeile mit ->fromArray(); schreiben
Der Arbeitsspeicher kann an 3 Stellen gesetzt werden.
PHP Script:
|
1 |
ini_set('memory_limit', '32M'); |
.htaccess Datei
|
1 |
php_value memory_limit 32M |
php.ini
|
1 |
memory_limit = 32M |
Ganz klar muss man aber sagen,man kann wohl optimieren so viel man möchte, aber um die 1 KiloByte pro Zelle Geschichte kommt man nicht rum bei der Verwendung von PHPExcel 1.7.7 (-:
Weitere spannende Beiträge zum Thema PHPExcel und dem Arbeitsspeicher / Memory – Leaks


