cakephperの日記(CakePHP, Laravel, PHP)


継続的WebセキュリティテストサービスVAddyを始めました!

2010-02-15

Ktaiライブラリ入門

cakephp 1.2.6で開発してます。

Ktaiライブラリを使ってみました。そのメモ

お手軽に携帯の対応ができるのでオススメです。ライブラリの公開感謝です!

画面出力はSJIS-winで、Cake側は全てViewファイルも含めてUTF-8です。モバイル用のコントローラは独立させてます。

画面出力の文字コード変換は、ヘルパー側でやるようなので、絵文字使わなくてもヘルパーの設置は必須です。vendorsは/app/vendorsじゃなくて、appと同じ位置にあるvendorsディレクトリなので注意が必要です。

1. ktai libraryをダウンロードして設置

ここからダウンロード。

下記のように設置

/app/app_controller.php ← 既存ファイルがある場合は、redirect()の内容だけをコピー

/app/controller/component/ktai.php

/app/config/ktai_session.php

/app/views/helpers/ktai.php

/vendrs/ecw/ ←ecwフォルダごとコピー


2.コントローラを設定

<?php
class HogeMobilesController extends AppController {

    var $name = 'HogeMobiles';
    var $uses = array('Hoge');

    var $helpers = array('Html', 'Form', 'Ktai');
    var $viewPath = 'hoge_mobile';
    var $layout = 'mobile';

    var $components = array( 'Ktai');

    var $ktai = array(
            'enable_ktai_session' => true, //セッション使用を有効にします
            'use_redirect_session_id' => false, //リダイレクトに必ずセッションIDをつけます
            'imode_session_name' => 'csid', //iMODE時のセッション名を変更します
            'input_encoding'  => 'UTF-8', //入力をUTF-8に変更
            'output_encoding' => 'SJIS-win', //出力をSJIS-winに変更
            'output_auto_encoding' => true, //出力を自動変更(KtaiHelperの中で)
             );

3. Viewファイルを編集

viewファイルはコントローラ側で設定した、下記のようになります。

レイアウトファイル: views/layout/mobile.ctp

各viewファイル: views/hoge_mobile/*.ctp

レイアウトファイル、各viewファイルはUTF-8で保存します。ただし、レイアウトファイルの中で、charsetをSJISに変更します。

<head>
    <?php echo $html->charset('Shift_JIS'); ?>
</head>

基本的にはこれでOKです。これだけでこのコントローラモバイル対応になりました。セッションURLの中に自動で付与され、Viewの文字コードSJISになります。

最後に、POSTされるデータはSJISで来るので、php.iniで自動変換をかけるか、beforeFilterで$this->dataをコンバートする必要があります。

コントローラのbeforeFilterで下記のようにすればOK.複数コントローラで使う場合はコンポーネント化したほうが良いです。

function beforeFilter() {
  if(!empty($this->data)) {
    mb_convert_variables( 'UTF-8', 'SJIS-win' ,$this->data);
  }
  parent::beforeFilter();
}

beforeFilterで自前でやる場合は、昔書いた記事の最後にあるので参考にしてください。

http://d.hatena.ne.jp/cakephper/20081001/1222866102

追記

core.phpでdebug値を0にしておかないと、セッションIDの自動付与は動かないっぽいので注意が必要です。

2008-10-01

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


class AppController extends Controller {

	//UTF8でレンダリングされたHTMLデータをSJISに変換
	function convert_output_encode(){

		$this->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なんていう便利な機能があったんですね。これで配列ごと文字コード変換ができて良い感じ。(ただし配列のキーは変換されないので英語にしたほうが良いです)

2008-09-26

Net_UserAgent_MobileをcakePHP1.2RC2で使う

携帯キャリアの判定に, PearのNet_UserAgent_Mobileを使う方法。まず、下記からNet_UserAgent_MobileとPearをダウンロード

http://pear.php.net/package/Net_UserAgent_Mobile/

http://pear.php.net/package/PEAR


UserAgentMobileのファイルを展開すると、mobile.phpとMobileフォルダが出来るので、下記のディレクトリのように設置。PEARも展開するといくつかファイルがあるので、PEAR.phpを下記のように設置。

app
 |-vendors
      |-PEAR.php
      |-Net
         |-UserAgent
              |-Mobile(ディレクトリ)
              |-Mobile.php


app/vendors/pear_ini.phpファイルを作成

<?php
    ini_set('include_path', dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
?>


例えば、mobileというコントローラで呼ぶ場合

app/controllers/mobile_controller.phpを下記のように作成

<?php

App::import('Vendor', 'pear_ini');
App::import('Vendor', 'Net/UserAgent/Mobile', array('file' => 'Net' . DS . 'UserAgent' . DS . 'mobile.php'));

class MobileController extends AppController {
	var $name = 'Mobile';
	var $layout = '';

	function index( ) {

		$agent = &Net_UserAgent_Mobile::factory();

		switch( true )
		{
		  case ($agent->isDoCoMo()):   // DoCoMoかどうか
		    //Docomo用の処理
		    break;

		  case ($agent->isSoftBank()): // softbankかどうか
		    //Softbank用の処理
		    break;

		  case ($agent->isEZweb()):    // ezwebかどうか
		    //Au用の処理
		    break;

		  default:
		    //PC用の処理
		    break;
		}
	}

}

?>

上記の例だと、エージェントを判定して、それぞれ処理を実行する場合の基本パターン。

cakephp1.2RC2だと、vendor('hoge');というようなインポート関数が非推奨になり、ワーニングが出るので、App::importを使う。