bz0のにっき

quick and dirty prototype

CSV読込して配列化 その2

CSV読み込むときに気を付けることをまとめてみました。

メモリを極力使わないようにする

ストリームを利用する

・大容量のCSVを読み込む際はストリームで「文字コード変換」を行う
 ストリームを利用すればメモリサイズを気にしなくてよくなる為

・ストリームフィルタを利用する際、iconvフィルタの利用は避ける
 iconvフィルタは不正なバイトが含まれていると全体を0バイトに変換してしまう
 http://d.hatena.ne.jp/hnw/20090317

CSVを一度に配列化してしまうと容量が大きい場合メモリを食いすぎる
 「 Stream_Filter_Mbstring」を使ってファイルを一行ずつ取得する
 http://nob-log.info/2012/04/17/stream_filter_mbstring/

エンコードの扱い

・文字エンコーディングの取り扱いはphpの各関数の実装に委ねられる

ロケールについて

・fgetcsv()はsetlocaleの影響を受ける
 ロケールhttps://wiki.archlinux.jp/index.php/%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB
 
 ・ロケールとは
   ロケールはOSが持っている多言語対応の仕組み。
  利用する言語 / 文字エンコードの設定を行うことが出来る。

 ・環境によりsetlocaleが効かない
  https://mgng.mugbum.info/1014
  ※Windows では setlocale(LC_ALL, 'ja_JP.UTF-8') は効かない

・setlocaleの挙動はOSのロケールの挙動に依存しており
 かつ大抵の環境の Shift_JISロケールは腐っている

ロケール設定はプロセス全体に影響する。
 マルチスレッドサーバで実行した場合、ほかのスレッドのロケール設定に影響を受ける

結論

・fgetcsv()はロケールに影響を受ける
 環境によってsetlocaleが効かない / マルチスレッドサーバで実行したときに他のスレッドの
 ロケール設定に影響を受けるかもしれない事に注意する。

・大容量のCSVの読込を行う場合は、メモリ対策の為にストリームを利用する