foldrr's weblog

旧ブログ http://d.hatena.ne.jp/foldrr/

php で fgetcsv() を使ってはいけない

CSV ファイルのパースをするには fgetcsv() という関数を使えばいい、と思うと文字化けでハマる。
マニュアル↓を見てみると、

PHP: fgetcsv - Manual -
http://jp.php.net/fgetcsv

注意: この関数はロケール設定を考慮します。
もし LANG が例えば en_US.UTF-8 の場合、
ファイル中の 1 バイトエンコーディングは間違って読み込まれます。

日本語でおk
もーこれじゃ意味分かんないって。
簡単に言うと

読み込みたい CSV ファイルと OS の LANG 環境変数の値が異なる場合、
文字化けが起きますよ。きっと。

といっても CSV 読み込みのためだけにロケール設定を変えるのはマズい。
影響範囲が広すぎる。
じゃぁどうすればいいのか?
「fgetcsv を自前で実装汁」ということみたい。(´・ω・`)

  • 自分で fgets して(しかもダブルクォート対応して)
  • 読み込んだ内容を mb_convert_encoding して
  • 変換後の内容をパースする

という面倒なことをしなくちゃいけない。
ネットを漁ればサンプルは沢山出てくる。

特に最後のパースが面倒。
「文字列を CSV としてパースする関数は無いの!?」と思って探すとこんなものがあった。

PHP: str_getcsv - Manual-
http://jp2.php.net/str_getcsv

ところがコレはまだ未実装(というか CVS にしかない?)なので、レンタルサーバじゃ確実に使えない。
PHP 面倒だよー。