PHPでの文字化けというかコード変換に関する注意
追記
いぇーい。ツッコんでもらえたぜ。id:elf:20070905 ハードコードしたやつをそのままechoしたらアカンでというメモだったんだけど、ちゃんと突っ込んでもらえた。mb_regex_encoding()というのは、気付いていませんでした。ありがとうございます。でもほとんどの場面で、preg_match()を使用しているのでどういう使い方をするか迷うところです。
本文
EUC-JPだけで文字化け知らずでいたのだが、UTF-8で多国語対応にするのにはまってしまった。
まずは結論から。
PHPの http_output(), mb_internal_encoding()とかの mb_string系の設定はわけわからん。したがって自動変換をしないようにするのが最も早い解決法だ。*1
HTMLのヘッダでのエンコード宣言と実際の出力コードの違いが、混乱の元になっていたように思う。きちんと統一しようぜというのが結果です。
PostgreSQL = UTF-8、入出力 = UTF-8、スクリプト = EUC-JP の場合
default_charset = UTF-8 mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_input = auto mbstring.http_output = UTF-8 mbstring.detect_order = UTF-8,eucjp-win,sjis-win,ISO-2022-JP,ASCII mbstring.encoding_translation = Off mbstring.substitute_character = none
- default_charset = UTF-8
- httpヘッダの charset として使われる。無いと困る。
- mbstring.language = Japanese
- mb_send_mail()のみ使用?ようわからんが無いと困る。
- mbstring.http_input = auto
- 決め打ちしたほうがいいけど、ま、どっちでも大丈夫そうだね。
- mbstring.http_output = UTF-8
- ob_stert('mb_output_handler') && text/ の時に headerで出力されるエンコード指定。大抵は output_handler = 'mb_output_handler' しているので出力バッファ時にコード変換を自動でしてしまいます。したがって正しく宣言しておいたほうが良い。
- mbstring.detect_order = UTF-8,eucjp-win,sjis-win,ISO-2022-JP,ASCII
- そうそう当てには出来ないが、やられては困る判定を後ろに追いやるべき。*3
- mbstring.encoding_translation = Off
- POSTとかで受け取る値を internal_encoding に自動で変換してくれる。ここをOffにするというのは、要するに決め打ちでトラブルを抑えるという意味なんですがね。
- 別件、ini_set()で値を上書きできないんです。どういうことなんすかね。兎に角、php.ini で正しくOffにしてやる必要がある。
- mbstring.substitute_character = none
- 余計な文字を消してブラウザ側での文字化けを抑える設定らしいが、余計にややこしくなりそうなので殺しておく。