cakeはUTF8で、入出力だけSJIS変換
モバイルとか、既存のSJISで作られたシステムの移行とかで、どうしてもhtml側はSJISにしたいけど、cake使うからこの際システムやDBはUTF8ベースにしたい、そんな感じのことをやる場合。
入力(POSTなど)でphp側で文字コード変換をしてない場合を前提としています。環境はcakePHP1.2RC2です。
Viewファイル、レイアウトファイル、エレメントファイルは全てUTF-8Nで保存しておきます。UTF-8Nですよ、UTF-8で保存してると、?などが先頭に表示されちゃいますから。これで10分ぐらいはまったのですorz
Viewファイルのhtmlは、文字コードはUTF-8Nですが、html側のcharsetはSJISにしておきます。
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
やるべきことは、コントローラの中でPOSTデータをSJISからUTF-8にすることと、html出力を全てSJISからUTF-8にすることです。とりあえずコントローラファイルの最初に下記のようなメソッドを用意しておきます。
app/controllers/hoge_controller.php
<?php class HogeController extends AppController { //出力文字コード変更(UTF8からSJIS) function afterFilter(){ $this->convert_output_encode(); } //入力文字コード変更(SHIS-winからUTF8) function beforeFilter(){ $this->convert_input_encode(); }
上記のコントローラでは、出力するHTMLの文字コードを変更するためにafterFilterでアクションの実行後にapp_controller.phpにこれから記載するconvert_output_encode()メソッドを呼んでいます。(afterFilterで呼ばないと、全ての出力結果を文字コード変換できないため)
入力(POST)されたデータは、アクションを実行する前に、app_controller.phpにこれから記載するconvert_output_encode()メソッドを呼んでいます。
では、最後にapp_controller.phpを下記の場所に作ります。
app/app_controller.php
output = mb_convert_encoding($this->output,'Shift_JIS','UTF-8'); } //POSTされたデータをSJISからUTF8へ変換 function convert_input_encode(){ if( !empty($this->data) ){ mb_convert_variables('UTF-8', 'SJIS-win',$this->data);array_walk_recursive($this->data, array('AppController', 'convert_input_encoding') );} }function convert_input_encoding( &$item, $key ){ $item = mb_convert_encoding( $item, 'UTF-8', 'SJIS-win' ); }} ?>
まず、convert_output_encodeでは、すべてレンダリングされた結果のhtmlが$this->outputに入っているので、$this->outputに対してmb_convert_encodingして文字コード変換しています。変換結果を$this->outputに入れてやれば、それがHTMLとして出力されます。
次にconvert_input_encodeでは、POSTデータがあるかチェックし、データがあれば$this->dataを再帰的に文字コード変換していきます。実際の文字コード変換はその下のconvert_input_encodingメソッドを呼んでいます。convert_input_encodingでは、再帰的に配列をたどって渡されたデータを文字コード変換しています。
こんな感じで、お手軽に変換してもらえます。いやぁ便利!
追記
mb_convert_variablesなんていう便利な機能があったんですね。これで配列ごと文字コード変換ができて良い感じ。(ただし配列のキーは変換されないので英語にしたほうが良いです)