【PHP】Shift-JISにエンコードしたCSVが文字化けするのはBOMが原因?

PHPでShift-JISにエンコードしたCSVをダウンロードする機能を実装したのですが、日本語の文字化けが発生。

原因はPHPファイルの文字コード」でした。

なかなかこの原因にたどり着けずに、解決時間がかかってしまいました。

解決方法のみ知りたい方の為に先に解決方法を。

PHPファイルがBOM付きのShift-JISになっていたら、PHPファイルをBOM無しのUTF-8に変換する

では、事象の内容と解決方法を詳しく解説していきます。

目次

【発生事象】Shift-JISに変換しているCSVのダウンロード処理でのみ文字化けする

まずは、どのような状況で発生したのか整理します。

文字化けするのはダウンロードするCSVのみです。
通常のWebページは文字化けせず正常に表示されています。

文字コードは、通常のページは全てUTF-8で、CSVダウンロードの時のみ、mb_convert_encodingShift-JISにエンコードしています。

エンコードのソースコード(調査の結果このソースコードには問題は無いことがわかりました)

mb_convert_encoding($str, 'sjis', 'utf-8');

このPHPシステムと全く同じものを、他のPCやサーバーでも動かしていますが、この事象が発生するのは、新規にセットアップした1台のPCでのみ発生しています。

ソースコードも同じですし、php.iniの文字コード関連も見直しましたが改善しませんでした。

【調査】実はShift-JISのエンコードは出来ていたがBOMが付いている

実際に行った調査 の内容について。

Shift-JISへのエンコードは出来ている

文字コードを指定できるツールで文字化けしているCSVをShift-JISで開いてみる事に。

IE(Internet Explorer)で簡単に文字コードを指定して開けます。
csvの拡張子を、txtに変更してIEにドラッグ&ドロップしてみます。
(csv拡張子のままだと、素直に開いてくれませんでした。)

開けたら画面を右クリック、「エンコード」→「日本語(シフトJIS)」とクリックすればOK。

この方法でShift-JISで開いたら、文字化けせずに表示されました。

ということは、Shift-JISのエンコードは問題ないのに、なぜEXCELなどで開くと文字化けするのか…

BOMが付いている!

そこで、SublimeTextでファイルを開いてみました。

Shift-JIFにエンコードしているはずなのに、なぜかUTF-8 with BOMとして認識されていました。

【原因】BOMヘッダが付加されてUTF-8と認識される

どうやら大概のツールは文字コードを判定する際にBOMヘッダが付加されていると実際の文字コードに関係なくUTF-8で開くようです。

Shift-JISにエンコードしているのに、UTF-8で開いていたら文字化けして当然ですね。

このCSVは、Shift-JISなのにBOMが付いているから、ツールがUTF-8と勘違いして文字化けして表示しているって事です。

これはなかなか気づきませんね。
普段BOMなんて気にしてませんし、なんでBOM付いているのか謎ですしね。

【解決方法】PHPファイルをBOM無しのUTF8に変換する事で解決

ではなんでBOM付きのShift-JISのファイルが出来上がってしまったのでしょうか?

PHPは、「ソースファイルがBOM付きだとechoした結果にもBOMが付く」のです。
require_onceしたファイルのどれかにBOMがあっても同様です。

ようするに。
Shift-JISにエンコードしているが、PHPファイルがBOM付だと、BOM付きのShift-JISのCSVを出力するんです。
ツールは「BOMが付いてるからUTF-8」と判断して、文字化け発生するという流れです。

PHPファイルをBOM無しのUTF-8でしていれば、基本的にこの事象は発生しません。
もちろん、今回のプロジェクトでもBOMありで開発していたわけではないんです。

なのに、なぜ事象が発生したのか。

今回は新しい環境にモジュールをセットアップしたのですが、その時に環境依存のconfig系のPHPをさくっとメモ帳で修正していました。

メモ帳はUTF-8をBOMありでしか保存出来ないのです。
なので、メモ帳で修正を保存した時に、BOMが勝手に追加されていたのでした。

という事で、そのPHPファイルをBOM無しのUTF-8に変換する事で、文字化けは解決しました

まとめ:PHPファイルをメモ帳で修正しない

PHPファイルをメモ帳で更新したことが原因でした。
今回の問題は原因の特定にかなり時間がかかってしまいました。

メモ帳ではPHPのファイルを修正しないようにしましょう。

この記事が少しでも参考になれば幸いです。

最後までお読み頂きありがとうございました。

おすすめ記事

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次