LoginSignup
18

More than 3 years have passed since last update.

phpspreadsheetは明示的に解放する必要がある

Last updated at Posted at 2019-05-19

概要

  • phpoffice/phpspreadsheetでは明示的に解放しないとメモリを確保しつづけるようで、特に複数のファイルを一括してバッチ処理するような場合にはメモリ使用量が急増する。
  • 関数の中でローカル変数として生成したインスタンスでもメモリは解放されない。
  • 解放はdisconnectWorksheets()してからgarbageCollect()

環境

コードで比較

A列を全行読み出すだけの関数

function without_disconnect($xls_file) {
  $xreader = new PhpOffice\PhpSpreadsheet\Reader\Xls();
  $xls = $xreader->load($xls_file);
  $sheet = $xls->getSheet(0);
  foreach ($sheet->getRowIterator() as $row) {
    $val = $sheet->getCell("A".$row->getRowIndex())->getValue();
  }
}

読み出した後に解放する関数 (2行追加)

function with_disconnect($xls_file) {
  $xreader = new PhpOffice\PhpSpreadsheet\Reader\Xls();
  $xls = $xreader->load($xls_file);
  $sheet = $xls->getSheet(0);
  foreach ($sheet->getRowIterator() as $row) {
    $val = $sheet->getCell("A".$row->getRowIndex())->getValue();
  }
  $xls->disconnectWorksheets();// 追加
  $xls->garbageCollect();// 追加
}

実行して比較

上記の2つの関数を3回ずつ呼んで、メモリ使用量を出力する。

メモリ使用量を出力する関数
function echo_mem($prefix='') {
  print($prefix.':');
  print(floor(memory_get_usage() / 1024).'KB'.PHP_EOL);
}

解放しない

without_disconnect
$f = __DIR__.'/tp20180314-01_05.xls';
echo_mem('before');
for ($i = 0; $i < 3; $i++) {
  without_disconnect($f);
  echo_mem('without'.$i);
}
結果
before:654KB
without0:53921KB
without1:103656KB
without2:156463KB

解放する

with_disconnect
$f = __DIR__.'/tp20180314-01_05.xls';
echo_mem('before');
for ($i = 0; $i < 3; $i++) {
  with_disconnect($f);
  echo_mem('with'.$i);
}
結果
before:654KB
with0:14973KB
with1:14973KB
with2:14973KB

追記2019-05-26 他のシートを開きたい時は解放してはいけない

disconnectWorksheets()した後で別のシートを開こうとしてもnullが返る。

// 1つ目のシートを開く
$sheet = $xls->getSheet(0);
/* 何か処理 */
$xls->disconnectWorksheets();
// 2つ目のシートを開きたい
$sheet = $xls->getSheet(1);
var_dump($sheet); // NULL

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18