2010年10月20日水曜日

PHPExcel1.7.4の不具合?について

以前PHPExcelのメモリ馬鹿食いについてで触れていたコードがPHPExcel1.7.4では正常に動作しないことが判明しました。

ワークシートオブジェクトのclone処理で、セルへの参照が1.7.4では上手くハンドリングされていないようで、書式が設定されたセルへ値を書き込むと、別のシートの同じセルにも値が書き込まれることがあります。

再現する条件を完全には洗い出せていませんが、書式が何も設定されていないプレーンなセルに対する書き込みは問題ありませんが、以下のような条件で別のシートの同じセルにも値が書き込まれることがあります。

・書き込むセルに既に値が入力されている
・書き込むセルがセル結合されている

他にもワークシート名の変更もちょっと動作が怪しいことがあります。

PHPExcelの1.7.4には不具合があるようです。
というよりも根本的な不具合があるのは1.7.3系で、PHPExcelのメモリ馬鹿食いについてで触れていたメモリリークっぽい現象を修正しようとして失敗しているようです。

セルのデータをキャッシュ(デフォルトではメモリ上に展開?)し、それを利用してセルのコピーやclone処理を行っているようですが、1.7.4系ではデータキャッシュのライブラリが格納されているClasses/PHPExcel/CachedObjectStorage配下が大幅に修正されています。

1.7.4は使用せずに1.7.3cに巻き戻した方が良さそうです。

1.7.3cではPHPExcel_CachedObjectStorage_Memcache.phpに明らかなバグ(単純ミス)があって気持ち悪いので、その箇所のみパッチ当てて使ってます。
ただし、このクラスはPHPExcel_Settingsを通して明示的にmemcachedをキャッシュオブジェクトとして指定しないと使われないようなので、デフォルト設定では実害はないようです。

以下、パッチ。

189行目
- if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback')) {
+ if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {

200行目
- throw new Exception('memcache '.$host.':'.$port' failed');
+ throw new Exception('memcache '.$host.':'.$port.' failed');

それから、PHPExcelのメモリリークを調べていた際に参考にさせて頂いたサイト【PHP】PHPExcelがループ内でメモリを使いすぎるで「さらに注意点としては、1.7.3cはaddExternalSheetにバグがあるので、最新のソースをダウンロードした方がいい。」との記述がありますが、これもPHPExcel.phpに以下のパッチを当てれば良さそう。

437行目
- $cell = $sheet->getCell($cellID);
+ $cell = $pSheet->getCell($cellID);

パッチを当てた1.7.3cで当分しのいで、1.7.4の修正版が出るのを待つ作戦をおすすめ。

0 件のコメント:

コメントを投稿