Summary
設定すべき項目は以下.
;; Disable Output Buffering
output_buffering = Off
;; Set HTTP header charset
; default_charset = EUC-JP
;; Set default language to Japanese
mbstring.language = Japanese
;; HTTP input encoding translation is enabled.
mbstring.encoding_translation = off
;; Set HTTP input encoding conversion to auto
mbstring.http_input = pass
;; Convert HTTP output to EUC-JP
mbstring.http_output = pass
;; Set internal encoding to EUC-JP
mbstring.internal_encoding = EUC-JP
;; Do not print invalid characters
mbstring.substitute_character = none
mbstring.detect_order = SJIS,EUC-JP,JIS,UTF-8,ASCII
誤解1: default_charsetはデフォルトの文字コードのことではない.
default_charsetは,出力時にHTTPヘッダとして送信する文字コード名のこと.
default_mimetype = 'text/html'
default_charset = 'utf-8' の場合
header('Content-Type: text/html; charset:utf-8');
が自動的に実行される.
Content-Typeが固定されるため,default_charsetは使用すべきではない.
誤解2: languageパラメータは内部言語のことではない.
languageパラメータは,mb_send_mailを利用した際にのみ使用される.
また,mb_send_mailは文字コードの変換を指定できないため,使用すべきでない.
PEAR::Mailで代替可能.
よって,languageパラメータは実質的に意味をなさない.
誤解3: internal_encodingは内部エンコードのことではない.
internal_encodingはmbstring関数のデフォルトエンコードのこと.
mb_convert_kanaなどで変換元文字コードの指定がない場合に使用される.
変換元文字コードを固定にするため,
internal_encodingはソースコードの文字コードと揃えておくと良い.
誤解4: http_outputを指定しても,自動的に文字コードは変換されない.
http_outputとは,mb_output_handlerが実行された時の出力エンコード.
ob_start("mb_output_handler")
と指定して初めて使われる.
また,http_outputの動作条件は,出力がtext/htmlである必要がある.
誤解5: detect_orderでautoを指定してはいけない.
detect_orderとは,文字コードの自動検出の優先順位のこと.
未指定の場合は,"auto" という値になるが,
"auto" は "ASCII,JIS,UTF-8,EUC-JP,SJIS" に展開される.
マルチバイトを扱う際に,ASCIIが最初にある点が問題.
出力する文字コードを先頭にし,JISやASCIIは最後の方に設定する.
結論
対策1: default_charsetを設定しない.
対策2: mb_send_mailを使用しない.
対策3: internal_encodingをソースコードの文字コードと揃える.
対策4: http_outputを使用しない.
対策5: detect_orderは必ず指定する.
Reference
PHPの文字化けを本気で解決する - ぎじゅっやさん
http://hain.jp/index.php/tech-j/2007/02/13/%EF%BC%B0%EF%BC%A8%EF%BC%B0%E3%81%AE%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91