携帯サイトhtmlの文字エンコーディングはShift_JISにするのが良いわけですが、ethnaに取り込まれているsmartyがEUC-JP推奨になっていて、Shift_JISだと内容によってsmartyがエラーを吐く場合があります(UTF-8なら問題は起きない、という情報もアリ。ジブンは未確認)。
そこで、ソースコードやテンプレートファイルはすべてEUC-JPで書いておいて、出力するときにShift_JISに変換して出力する、というやり方が良いです。
ethnaには入出力時に自動で任意の処理を行うフィルタ(filter)のしくみが用意されているので、これを用いるとコード中で文字コード変換する処理を極力減らすことができてすっきりします。
また出力時だけでなく、POSTされたデータを受け取るときの処理も同様です。フォーム入力されてPOSTされた日本語データは、元ページhtmlの文字エンコーディングのままで送られてきます(ただし例外アリ。auの場合、UTF-8でページを作っていても送られてくるデータはShift_JISの場合があります)。それをコード内で処理したりDBに格納したりするときの文字エンコーディングを統一させるのに、filterをつかうことでスッキリと処理できるようになります。
filterを使うには、ethnaプロジェクトディレクトリの app/filter/ のなかにfilterファイルを作って、Controllerの中にfilter名を記述すればOKです。
以下、filterの記述例です。
ソースコード自体はeucで記述しておいて、携帯からアクセスされた場合はShiftJISで、PCからアクセスされた場合はそのままeucで出力させるケースです。
中で使用しているNet_UserAgent_Mobileについてはこのへんとかを参照ください。
include_once('Net/UserAgent/Mobile.php');
class Hoge_Filter extends Ethna_Filter
{
// POSTされたデータを文字コード変換してからソースコード本体に渡す
function preFilter()
{
ob_start();
$agent = Net_UserAgent_Mobile::singleton();
if($agent->isDoCoMo() || $agent->isEZweb() || $agent->isVodafone())
{
//■携帯アクセスの場合は、受け取りパラメタのエンコードをsjis->euc変換
$_GET = Filter_convert_encoding_sjis2euc($_GET);
$_POST = Filter_convert_encoding_sjis2euc($_POST);
}
else
{
//■PCアクセスの場合はなにもしない
}
}
// 出力時に文字コード変換処理を行う(smarty変換処理のあとにコールされる)
function postFilter()
{
$content = ob_get_contents();
$agent = Net_UserAgent_Mobile::singleton();
if($agent->isDoCoMo() || $agent->isEZweb() || $agent->isVodafone())
{
//■携帯アクセスの場合
//xhtmlの場合はここでContent-Typeを出力
//header('Content-Type: application/xhtml+xml; charset=Shift-JIS;');
//エンコーディングをShiftJISに変換
$content = mb_convert_encoding($content, 'sjis-win', 'eucJP-win');
}
else
{
//■PCアクセスの場合はなにもしない
}
ob_clean();
echo $content;
ob_end_flush();
}
}
// 引数が配列の場合は中の要素を再帰的に処理
function Filter_convert_encoding_sjis2euc($value)
{
if(is_array($value))
{
return array_map('Filter_convert_encoding_sjis2euc', $value);
}
else
{
return mb_convert_encoding($value, 'eucjp-win', 'sjis-win');
}
}
ポイントはob_start()を使って出力をいったんバッファに入れておいて、最後に全部まとめて文字コード変換してから出力する、というやりかた。
これを記述しておくと、煩雑になりがちな文字コード変換処理を自動で行ってくれて、ソースコード本体がシンプルになって開発効率も向上!すると思います。超おすすめ。
・・って、エラそうに書いてますがWEB+DB PRESS 37に掲載されていたウノウさんのコードをかなり参考にさせていただいています。感謝。
ちなみにこのethna filterを使わなくとも、ob_start()とob_get_contents()あたりを組み合わせて使うと同様の処理が実現できるとおもいます。