PHPExcelのキャッシュ機能について
PHP上でExcelを使えるPHPExcelというライブラリについて勉強中。
PHPExcel
http://phpexcel.codeplex.com/
これを使って、以下の様なプログラムを書く。
<?php set_include_path(get_include_path() . PATH_SEPARATOR . './PHPExcel-1.7.5/Classes/'); include 'PHPExcel.php'; include 'PHPExcel/IOFactory.php'; $objReader = PHPExcel_IOFactory::createReader('Excel5'); $objPHPExcel = $objReader->load('sum.xls'); $sheet = $objPHPExcel->getActiveSheet(); $a1 = $sheet->getCell('A1'); $b1 = $sheet->getCell('B1'); $c1 = $sheet->getCell('C1'); echo "A1: " . $a1->getCalculatedValue() . "\n"; echo "B1: " . $b1->getCalculatedValue() . "\n"; echo "C1: " . $c1->getCalculatedValue() . "\n"; $b1->setValue(7); echo "A1: " . $a1->getCalculatedValue() . "\n"; echo "B1: " . $b1->getCalculatedValue() . "\n"; echo "C1: " . $c1->getCalculatedValue() . "\n";
A1=1, B1=3, C1=A1+B1のような内容のsum.xlsを用意して、このプログラムを動かすと、次の様な結果になる。
A1: 1 B1: 3 C1: 4 A1: 1 B1: 7 C1: 4
なんで? 2回目のC1は8になって欲しいのに。
キャッシュが効いてるんかな? と思ってデバッグモードで1行ずつ動かしていくと、不思議と2回目のC1は8という結果が出る。
ん?? 動作時間でキャッシュがクリアされる設計?
……とりあえず、1プロセス内で人間との対話をすることが少ないPHP専用のライブラリで、時間依存でキャッシュクリアされる設計には正直納得がいかないけれども、B1に7をセットした後に以下の行を付け足すことで、キャッシュクリアできることが分かりました。
PHPExcel_Calculation::getInstance()->clearCalculationCache();
これで動かすと、次の通り、成功。
A1: 1 B1: 3 C1: 4 A1: 1 B1: 7 C1: 8
なお、clearCalculationCacheを使う代わりに、include等が全部終わった後の初期化フェーズに以下の行を入れることでも、正しい結果が得られました。
PHPExcel_Calculation::getInstance()->setCalculationCacheEnabled(false);
setCalculationCacheEnabled(false)は、キャッシュクリアじゃなくて、キャッシュ機能ごと無効にしてしまう機能ですね。
キャッシュ自体は諸々の理由により必要な機能だと思うので、clearCalculationCacheを使うことをオススメ致します。