2017-08-17 1 views
1

J'ai un script qui lit les emails avec des fichiers Excel joints.
J'utilise PHPExcel pour analyser ces fichiers.PHPExcel ne libère pas de mémoire

Le problème actuel que je suis, est avec un email qui a cinq feuilles de calcul jointes.
Chaque fois que le cinquième fichier est chargé, PHP manque de mémoire.

Au début, j'essayé réduire à néant ($objPHPExcel = NULL;) et MHS (unset($objPHPExcel);) l'objet PHPExcel à chaque fois après avoir été jusqu'au bout il. Cela n'a pas aidé.

J'ai ensuite essayé d'ajouter la collecte des ordures au processus (gc_enable(); $cycles_collected = gc_collect_cycles();). Cela n'a pas aidé.

J'ai imprimé l'utilisation actuelle de la mémoire de php à mon journal d'erreurs et je peux le voir grandir avec le chargement de chaque fichier Excel dans PHPExcel, je peux aussi voir que l'utilisation de la mémoire ne diminue pas avec chaque NULL, unset ou gc_collect.

Voici une partie de la sortie de l'échantillon à mon error_log juste avant et après PHP à court de mémoire:

[17-Aug-2017 16:04:29 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 85575176 

[17-Aug-2017 16:04:32 America/Chicago] [Blackouts] Current Memory Usage after loading Excel file: 104474632 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after parsing of Excel file is complete: 104480416 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object set to null: 104480536 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object is unset: 104480256 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] gc collected cycles: 0 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after gc_collect_cycles: 104480416 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] script completed: /path/to/file/Schedule Week of 14 Aug 2017 - 21 Aug 2017.xlsx 

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 104484072 

[17-Aug-2017 16:04:36 America/Chicago] [Blackouts] Current Memory Usage after loading Excel file: 122069128 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after parsing of Excel file is complete: 122114480 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object set to null: 122114600 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object is unset: 122114320 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] gc collected cycles: 0 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after gc_collect_cycles: 122114480 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] script completed: /path/to/file/Schedules Week of 14 Aug 2017 - 21 Aug 2017.xlsx 

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 122118192 

[17-Aug-2017 16:04:39 America/Chicago] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted at Zend/zend_vm_execute.h:22207 (tried to allocate 72 bytes) in /mnt/nas_001_www/Classes/PHPExcel/Cell.php on line 551 
+0

Quelle est la taille de la dernière feuille? aime les lignes et les colonnes – bassxzero

+0

J'ai déjà retravaillé un projet utilisant phpExcel. Après avoir augmenté la mémoire et utilisé un serveur très performant, il a fallu très longtemps pour générer un Excel (5k + lignes). J'ai finalement optimisé mon extraction de données et suis passé à la génération d'un csv avec sep =; balise de métadonnées afin qu'il puisse être ouvert avec Excel. – Rienk

+0

Toutes les feuilles ont à peu près la même taille. La dernière feuille contient 9 colonnes et environ 1500 lignes. –

Répondre

2

Vous ne pouvez pas simplement annuler ou désactiver un objet PHPExcel pour le supprimer de la mémoire, as explained in the documentation, parce qu'il contient des références cycliques (le classeur contient une collection d'objets de feuille de calcul et chaque feuille de travail référence le classeur, de même que les objets de feuille de calcul et de cellule) qui ne peuvent pas être simplement résolus par un paramètre non défini. Au lieu de cela, vous devez d'abord casser ces références

$objPHPExcel->disconnectWorksheets(); 
unset($objPHPExcel) 
+0

Merci pour l'aide @ Baker Baker. Mais pourquoi ne pas simplement inclure la fonction disconnectWorksheets() dans le destructeur de la classe PHPExcel afin que le développeur n'ait pas à l'appeler explicitement? Je suis sûr qu'il y a une bonne raison à cela ou c'est juste un manque de compréhension de la fonctionnalité de la classe. Merci encore! –

+0

Théoriquement, il pourrait l'être, bien qu'il y ait quelques circonstances où il doit être appelé indépendamment; mais mon souvenir quand il a été écrit il y a un an, c'est que ça n'a pas fonctionné quand on l'appelait dans le destructeur .... mon souvenir est qu'il était lié au timing/ordre d'exécution des destructeurs en bas de la liste de travail to worksheet to cellcollection aux cellules –

+0

Assez juste. Merci encore Mark! –