さて、前回記事「PHPでメモリ上に一時ファイルを作る」では、file_get_contents関数でCSVファイル全体を取得して文字エンコーディングの変換を行い、変換結果に対してfgetcsv関数を利用しました。しかし、CSVファイルが巨大な場合にはfile_get_contentsを使うとメモリ上限に引っかかってPHPが停止してしまいます。
もちろん、UTF-8のCSVファイルに対してfgetcsvを利用するのであれば、どんな大きなCSVファイルだろうと処理することが可能です。なぜなら、fgetcsvはファイルを1行単位で読み込む関数ですから、1行分のメモリ消費だけでファイル全体を読み込み続けられるからです(正確にはストリーム上のデータはバッファリングされるので、バッファサイズ分のメモリは消費しますが)。
それでは、巨大なSJISのCSVファイルをfgetcsvで処理したい場合はどうすれば良いのでしょうか。このような場合には、ストリームフィルタが便利です。ストリームフィルタというのは、ストリーム上に流れる文字列を加工するための仕組みです。今回、Stream_Filter_Mbstringという、文字エンコーディング変換を行うストリームフィルタを作ってみました。
続きを読む