1. 程式人生 > >PHPExcel解決記憶體佔用過大問題-設定單元格物件快取

PHPExcel解決記憶體佔用過大問題-設定單元格物件快取

PHPExcel解決記憶體佔用過大問題-設定單元格物件快取

PHPExcel是一個很強大的處理Excel的PHP開源類,但是很大的一個問題就是它佔用記憶體太大,從1.7.3開始,它支援設定cell的快取方式,但是推薦使用目前穩定的版本1.7.6,因為之前的版本都會不同程度的存在bug,以下是其官方文件:

 

PHPExcel uses an average of about 1k/cell in your worksheets, so large workbooks can quickly use up available memory. Cell caching provides a mechanism that allows PHPExcel to maintain the cell objects in a smaller size of memory, on disk, or in APC, memcache or Wincache, rather than in PHP memory. This allows you to reduce the memory usage for large workbooks, although at a cost of speed to access cell data.

 

PHPExcel平均下來使用1k/單元格的記憶體,因此大的文件會導致記憶體消耗的也很快。單元格快取機制能夠允許PHPExcel將記憶體中的小的單元格物件快取在磁碟或者APC,memcache或者Wincache中,儘管會在讀取資料上消耗一些時間,但是能夠幫助你降低記憶體的消耗。

 

如果還是不夠,開啟php.ini改裡面的memory_limit

預設是128M調大點。

 

 

 

 

By default, PHPExcel still holds all cell objects in memory, but you can specify alternatives. To enable cell caching, you must call the PHPExcel_Settings::setCacheStorageMethod() method, passing in the caching method that you wish to use.

 

預設情況下,PHPExcel依然將單元格物件儲存在記憶體中,但是你可以自定義。你可以使用PHPExcel_Settings::setCacheStorageMethod()方法,將快取方式作為引數傳遞給這個方法來設定快取的方式。

 

 

Php程式碼  

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory;  

PHPExcel_Settings::setCacheStorageMethod($cacheMethod);  

 

setCacheStorageMethod() will return a boolean true on success, false on failure (for example if trying to cache to APC when APC is not enabled).

 setCacheStorageMethod()方法會返回一個BOOL型變數用於表示是否成功設定(比如,如果APC不能使用的時候,你設定使用APC快取,將會返回false)

 

A separate cache is maintained for each individual worksheet, and is automatically created when the worksheet is instantiated based on the caching method and settings that you have configured. You cannot change the configuration settings once you have started to read a workbook, or have created your first worksheet.

 

每一個worksheet都會有一個獨立的快取,當一個worksheet例項化時,就會根據設定或配置的快取方式來自動建立。一旦你開始讀取一個檔案或者你已經建立了第一個worksheet,就不能在改變快取的方式了。

 

Currently, the following caching methods are available.

 目前,有以下幾種快取方式可以使用:

 

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_in_memory;  

The default. If you don’t initialise any caching method, then this is the method that PHPExcel will use. Cell objects are maintained in PHP memory as at present.

 預設情況下,如果你不初始化任何快取方式,PHPExcel將使用記憶體快取的方式。

===============================================

 

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;  

Using this caching method, cells are held in PHP memory as an array of serialized objects, which reduces the memory footprint with minimal performance overhead.

 使用這種快取方式,單元格會以序列化的方式儲存在記憶體中,這是降低記憶體使用率效能比較高的一種方案。

===============================================

 

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;  

Like cache_in_memory_serialized, this method holds cells in PHP memory as an array of serialized objects, but gzipped to reduce the memory usage still further, although access to read or write a cell is slightly slower.

 與序列化的方式類似,這種方法在序列化之後,又進行gzip壓縮之後再放入記憶體中,這回跟進一步降低記憶體的使用,但是讀取和寫入時會有一些慢。

 

===========================================================

 

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;  

When using cache_to_discISAM all cells are held in a temporary disk file, with only an index to their location in that file maintained in PHP memory. This is slower than any of the cache_in_memory methods, but significantly reduces the memory footprint.
Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;  

Like cache_to_discISAM, when using cache_to_phpTemp all cells are held in the php://temp I/O stream, with only an index to their location maintained in PHP memory. In PHP, the php://memory wrapper stores data in the memory: php://temp behaves similarly, but uses a temporary file for storing the data when a certain memory limit is reached. The default is 1 MB, but you can change this when initialising cache_to_phpTemp.

 類似cache_to_discISAM這種方式,使用cache_to_phpTemp時,所有的單元格會還存在php://temp I/O流中,只把他們的位置儲存在PHP的記憶體中。PHP的php://memory包裹器將資料儲存在記憶體中,php://temp的行為類似,但是當儲存的資料大小超過記憶體限制時,會將資料儲存在臨時檔案中,預設的大小是1MB,但是你可以在初始化時修改它:

Php程式碼  

$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;  

$cacheSettings = array( ' memoryCacheSize '  => '8MB'  );  

PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);  

The php://temp file is automatically deleted when your script terminates.

php://temp檔案在指令碼結束是會自動刪除。

 

 

===========================================================

 

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_to_apc;  

When using cache_to_apc, cell objects are maintained in APC with only an index maintained in PHP memory to identify that the cell exists. By default, an APC cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_APC.

 當使用cach_to_apc時,單元格儲存在APC中,只在記憶體中儲存索引。APC快取預設超時時間時600秒,對絕大多數應用是足夠了,當然你也可以在初始化時進行修改:

Php程式碼  

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC;  

$cacheSettings = array( 'cacheTime'  => 600   );  

PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);  

When your script terminates all entries will be cleared from APC, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.

 當指令碼執行結束時,所有的資料都會從APC中清楚(忽略快取時間),不能使用此機制作為持久快取。

 

 

===========================================================

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_to_memcache  

When using cache_to_memcache, cell objects are maintained in memcache with only an index maintained in PHP memory to identify that the cell exists.
Php程式碼  

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache;  

$cacheSettings = array( 'memcacheServer'  => 'localhost',  

                        'memcachePort'    => 11211,  

                        'cacheTime'       => 600  

 );  

PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);  

 從初始化設定的形式上看,MS還不支援多臺memcache伺服器輪詢的方式,比較遺憾。

When your script terminates all entries will be cleared from memcache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.

 當指令碼結束時,所有的資料都會從memcache清空(忽略快取時間),不能使用該機制進行持久儲存。

 

 

===========================================================

Php程式碼  

PHPExcel_CachedObjectStorageFactory::cache_to_wincache;  

When using cache_to_wincache, cell objects are maintained in Wincache with only an index maintained in PHP memory to identify that the cell exists. By default, a Wincache cache timeout of 600 seconds is used, which should be enough for most applications: although it is possible to change this when initialising cache_to_wincache.

 使用cache_towincache方式,單元格物件會儲存在Wincache中,只在記憶體中儲存索引,預設情況下Wincache過期時間為600秒,對絕大多數應用是足夠了,當然也可以在初始化時修改:

Php程式碼  

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_wincache;  

$cacheSettings = array( 'cacheTime'  => 600 );  

PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);  

When your script terminates all entries will be cleared from Wincache, regardless of the cacheTime value, so it cannot be used for persistent storage using this mechanism.

 

 

PHPExcel還是比較強大的,最大的問題就是記憶體佔用的問題,PHPExcel啥時候能出一個輕量級的版本,不需要那麼多花哨的功能,只需要匯出最普通的資料的版本就好了!