PHPの文字化けについて

検索エンジンから文字化けや、文字コードで検索してこのブログにたどり着いた人が多いようですので、少し文字化けについて記事を書いておこうと思います。

PHPの機種依存文字の文字化けまとめ
の記事で書いた内容は、PHP内で明示的に文字コードを変換する内容ですが、それ以外の文字化けの原因を、徒然に書いていこうかと思います。

POSTやGETで飛んできた、ユーザー入力の値の文字化け

PHPをデフォルトで使っている場合、http_inputの値は以下のような感じだと思います。
サンプル(.htaccessに記述した場合):
php_flag mbstring.encoding_translation "On"
php_value mbstring.http_input "Auto"

encoding_translationがOnで
http_inputがAutoになっている場合は、
ユーザーのリクエストの文字コードを自動判別して、内部エンコーディングにあわせてくれるのですが、
detect_orderの値を適切に設定しないと、文字化けを起こします。
detect_orderは自動文字エンコーディング検出の順番です。カンマ区切りで記述し、前に来るほど優先度が高いです。
で、実際の設定ですが、
たいていのブラウザでは、表示している文字コードのエンコーディングでフォーム送信を行うため、
http_outputの値を先頭に持って来ないと、文字化けを起こすことがあります。
また、送られてきたPOSTデータの文字コードが、detect_orderに存在しない場合も、文字化けを起こします。

これは、mb_convert_encodingの第三引数でAutoを指定した場合も同様です。

また、入力文字数が少なすぎると、うまく文字コード判定できない時があるので、
<input type="hidden" name="_buff" value="あいうえお" />
と言うような、ダミーの値をhiddenで飛ばせば、誤検知を減らすことができます。

http_outputを指定しているのに、出力エンコーディングが変わらない。

これは簡単ですね。
下記設定を書き加えればokです。
サンプル(.htaccessに記述する場合):
php_value output_handler "mb_output_handler"

画像ファイルを出力しようとすると、壊れる/文字化けしたテキストデータが表示される

これも簡単。
上記の様な文字コード変換が動作してしまう為ですね。
下記のコードを書き加えれば解決です。
mb_http_output('pass');


metaタグで文字コードを指定して、PHPの出力もmetaタグ通りなのにブラウザが、エンコードを認識してくれない


例えば、UTF-8で出力しているのに、ブラウザがSJISで開こうとする場合は、
header('Content-Type: text/html; charset:utf-8');


というヘッダを出力すれば、解決するかと。
というような感じです。
他になんか文字化けネタってあったっけ?

ありましたら、コメントいただければ幸いです。