文字化けしないはずの仕組みで文字化け
メールフォーム作成の仕事で文字化け問題に直面した(文字化けなんてすごく久しぶり)。メールフォーム自体はすでにmojavi2で作成したベースがあるので、何のことはない。「超簡単」のはずだった。しかし文字化けが発生してしまった・・・。ちなみに今回の環境はスクリプトはEUC-JP、HTMLはSJIS。
最初は何が問題なのかわからなかった。だって文字化けしたことがなかったから。たいていのサーバでPHPのマルチバイト関連は何も設定されていないから、問題なかったのかもしれない。今回はサーバ側で既定の設定がしてあったことが原因のようだ。
問題解決のお決まりの手法だが、まず表示されたソースの文字コードをEUC-JPやUTF-8にしてみた。しかし、それでもうまく表示してくれない。どの文字コードにしてもうまく表示されないということは、間違った文字コード変換をしているか、もしくは元々のテンプレートが指定された文字コードでないか、どちらかだ。テンプレートをダウンロードしてみたがどうやら設定どおりになっている。ということは間違った文字コード変換をしているようだ。
間違った文字コード変換にも2種類ある。元の文字コードや変換先の文字コードを設定とは異なるコードに変換してしまうことと、文字コード変換を多重にしてしまう(1回でいいのに)ことだ。
このプログラムは他のサーバで正常に動いているところを見ると、間違った文字コード変換をしているとは考えにくい。ということは余計な文字コード変換をしてしまっていると考えた。
このプログラムでは、マルチバイトがらみの設定の影響を避けるため、プログラムの先頭で以下のように記述している。
mb_language(‘Japanese’);
mb_internal_encoding(‘EUC-JP’);
mb_http_input(‘pass’);
mb_http_output(‘SJIS’);
ob_start(‘mb_output_handler’);
まず原因は「ob_start(‘mb_output_handler’);」の記述だった。
実はこのサーバ、phpinfoで情報を見ることが出来ない(制限がかけてあるのだ)。いちおうお仕事の発注元経由で問い合わせをかけることは出来るが、それにしても時間がかかる。phpinfoを見ることが出来ないのは、問題解決をむずかしくする要因だった。ではなぜ上記の記述がNGなのか。
多分php.iniで「mb_output_handler」が設定されていて、そこで正しく変換しているのに、再度上記の記述で変換をかけたために文字化けしていたと思われる。
ということで、問題の行をコメントアウトして正しく表示されることを確認した。
しかし問題その2。入力した文字が確認画面で文字化けして表示される。もしやと思いencoding_translation(自動文字変換)が有効になっていないかチェックした。案の定、上記設定が有効になっていた。
プログラムとしては、SJISのHTMLから飛んでくるデータはプログラム内部で内部円コーディングに変換するように組んであるのだが、これが余計。自動変換されたものを再度変換しているのだ。で、その行をコメントアウト。
これで正しく表示されるようになった。
PHPプログラムの文字化け解決の教科書みたいな事例でした。