PHPでSJISなCSVファイルを読み込もうとして文字化け

  • 投稿日:
  • by
  • カテゴリ:
  • タグ:

ハマる定番みたいな事象なんですが、なかなか解決出来ずに小一時間あれこれ試しました。

環境は Windows 7 pro 64bit上で動く XAMPP 1.7.5 beta1 です。 Apache、PHP(MySQLも)の文字コードは UTF-8 にしています。
読み込むCSVファイルは、社内の購買システムが吐き出した購買実績で、ダブルクオーテーションは使わずカンマで区切っただけのシフトJISエンコーディングされたファイルです。

最初に見つけたのは「PHPのお勉強」さんの例。 読み込めましたが、文字化けします。 ページのエンコードをシフトJISにすると見えるようになりますが、先頭の日本語が化けたままです。

phpを勉強してみる」さんの事例は、fgetcsvのマニュアルに記載された例題に近いですが、やっぱり同じ状況ですね。 「Webにまつわるエトセトラ」さんのやり方も同様です。

「php csv 先頭 文字化け」でぐぐったら、「PHPプロ!」さんにそのものズバリの質問があって、yossyさんの fgetcsv_reg を見つけることが出来ました。 これで解決できました。
ただ使い方の例の中で

mb_convert_variables($_enc_to,$_enc_from,$data);

となっている部分は、

mb_convert_variables('UTF-8', 'sjis-win', $data);

に変更しました。 最初は「sjis」としていたんですが、CSVファイルに機種依存文字が含まれていたので、「sjis-win」としました。


その後、の「日本語の先頭が化ける」原因について、「Pentan.info」さんの解説から、CSVファイルを読み込む前に、

setlocale(LC_ALL, 'ja_JP.UTF-8');

を実行すればよいということがわかりました。 これで、fgetcsv_reg を使わなくても「PHPのお勉強」さんのやり方で化けなくなりました。 こちらの方が処理が速いです。

CSVファイルの読み込み方法の違いによる処理速度の比較では「130単位」さんの記事が興味深いです。 「PHPのテクメモ」さんの方法も試してみましたが、今までと違う部分で文字化けします。 なんでだろ?

他にもCSVファイルを読み込む際の注意点は「Asial blog」さんの記事が参考になりました。
今回はそれほどサイズの大きなファイルではありませんでしたが、今後「hnwの日記」さんのような方法も必要になってくるかもしれません。
先人の知恵に感謝です。


その後、購買システムから新たにCSVファイルをダウンロードしたら、今度はダブルクオーテーションで囲まれてました。 仕様変更されたのかな?
fgetcsv には、ダブルクオーテーションを取り除く機能があるので便利ですね。