PHP

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

投稿日:2017年11月21日 更新日:


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

この問題がちょっとややこしくて解決するのに時間がかかりました。

なんと文字化けの原因はソースコードではなくて、PHPファイルの文字コードだったんです。

これはなかなか気づきませんね。
同じような事象でハマっている方の参考になればと思い解決方法を解説します!

スポンサーリンク

【発生事象】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でファイルを開いてみました。

UTF-8 with BOM!?

確かにShift-JIFにエンコードしているはずで、エンコードもうまくいっているはず。
なのになぜかUTF-8 with BOMとして認識されている!

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

原因はこのBOMなんですね。

どうやら大概のツールは文字コードを判定する際に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でしてますよね。
なので、基本的にこの事象はおきないのですが…

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

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

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

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

予想外の所に原因がありましたね!

そもそもPHPファイルはメモ帳で修正したらダメなんですね!
どこかでこんな教訓を見たような気もしますか、すっかり忘れてました。

実際に体験すると身につくものですね!

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

スポンサーリンク


-PHP

執筆者:

関連記事

【EC-CUBE】新しいフロントページを追加する方法

EC-CUBE2で新規にフロントページを追加する方法の解説です。 スポンサーリンク 目次dtb_pagelayoutにレコードを追加するPHPファイルを作成ページクラスを作成テンプレートファイルを配置 …

【PHP】大きいリモートファイルをfreadすると途中で切れる【理由と解決法】

PHPでリモートファイル(httpやsshで読み込むファイル)をfreadする際、容量の大きいファイルを読み込むと、読み込みが途中で切れる事があります。 エラーなど発生せず、freadの結果が読み込み …

【PhpStorm/MAMP】デバッグ中にphpMyAdminで中断してしまう場合の対処方法

PhpStormでデバッグしていると、なぜかphpMyAdminで一時停止してしまう問題。 開発環境は、ローカルのMAMPです。 phpMyAdminを使う時は毎回デバッグをOFFにしていたのですが、 …

【EC-CUBE2】 SQLをデバック出力する方法

EC-CUBE2で実行されるSQLをデバッグ出力する方法について。 コードをコピペする事で、実行されたSQLを画面にデバッグ出力できます。 スポンサーリンク 目次EC-CUBE2でSQLをデバックする …

RewriteEngine onで403エラーの解決方法

ローカル環境でRewriteEngine onにしたら、403エラーが発生。 その解決方法の解説です。 スポンサーリンク 目次環境についてFollowSymLinksを有効にする事で解決まとめ 環境に …

プロフィール

このサイトを運営しているDENです。
アングラーのフリープログラマー。 主にプログラミングと釣の話を発信しています。
プログラミングで自由になり思う存分に釣りをしまくる生活実践中。
詳しいプロフィールはこちら 
フォスターフリーランス