文字化け

上鍵さんからツッコミが入ってますが、別の点を。

先ほどの例の時にも書いたが、PHPには内部エンコードという概念は存在しない。ではmbstring.internal_encodingとは何なのか。これは
mbstring関数のデフォルトエンコード
なだけである。

しかし、変換元が固定になるというのは重要なことなので、
これはソースコードと揃えておくのがBetter。

変換元て。mbstring の関数てエンコーディング変換だけじゃないんだけどなぁ。mb_strlen だって mb_ereg 系の関数だってデフォルトのエンコーディングは mbstring.internal_encoding になるわけで、ソースコードと揃えるのは「Better」というより「原則」だろう。全ての mbstring 関数でいちいち指定したいなら別だけど。

detect_orderは必ず指定する

えーと、本気で文字化けを解決したいなら、そもそも自動検出に依存しないようにするべきだろう。1年近く PHP のコードを書いてないけど、"detect_order を二次的に利用する" 必要性なんてあったかなぁ。外部リソースを読む必要があって、それがユーザ指定の場合(はてなブックマークとか Web 魚拓とか)ぐらいしか思いつかない。

http_outputは指定するだけでは何も動作しない。
これはmb_output_handlerが実行された時の出力エンコードに過ぎない。

ob_start("mb_output_handler")

と指定されて初めて使われるのだ。

また、微妙に誤解を振りまく記述だなぁ。php.ini に

output_handler = "mb_output_handler"

て書いておくと自動的に ob_start('mb_output_handler') される。鵜呑みにしていると軽くはまれます。

ob_startを実行しても、すべての出力に適用されるわけではない。http_outputの発動条件は

出力がtext/htmlである

必要がある。なのでapplication/xmlとかをヘッダーで投げていると動かないのだ。

微妙にダウト。正しくは Content-type が "text/" で始まっている場合にのみ動作する。まぁ Content-type: application/xml のときに変換されないのは正しいけど。つうか、マニュアル読め。

でも自動変換に依存しないという方針には賛同できるかな。
エンコーディング変換の必要な箇所(入力パラメータの変換、urlencode する文字列の変換、出力ページの変換 等など)はライブラリとしてまとめておくか、設定1つで切り替わるようなフレームワークにしておくべきだと思うけどね。

些細なこと

上鍵さんもミスしてますが、Content-type の出力は

header('Content-Type: text/html; charset:<CHARSET>');

じゃなくて、

header('Content-Type: text/html; charset=<CHARSET>');