fc2ブログ

price-change:blog

色んな情報テンコモリ

CodeIgniter | PCとモバイルのview切り替え

同じURLでPC用のviewとモバイル用viewをユーザーエージェントで切り替えられたらいいなー、と思って今回も頑張ってみた。

ユーザーエージェントを判別するためにPEAR::Net_UserAgent_Mobileを使う手もあるけど、ここはあえてCodeIgniteruser_agentライブラリを使ってやってみるのだ。

まずは、application/config/user_agents.php 内で $mobiles 配列にユーザーエージェントを定義しなくてはなんねだ。どう定義したらいいかよく分からなねから、ライブラリを覗いてみたら、どうやら配列のキーで判別しているようだわさ。配列のキーは小文字にしなきゃいけねだよ。んで、値にユーザーエージェント名を書くだ。古い機種のは面倒臭いから現行のに統一しただ。au は ezweb の方がいいだべか?


'docomo'     => 'DoCoMo',
'vodafone'   => 'SoftBank',
'j-phone'    => 'SoftBank',
'softbank'   => 'SoftBank',
'kddi-'      => 'au',
'up.browser' => 'au',
'willcom'    => 'WILLCOM',
'ddipocket'  => 'WILLCOM'

んで、コントローラを書いてみただ。_outputメソッドで携帯用に文字コードをSJISに変換してるけど、これはフックしたほうがいいら?わからんわぁ。


<?php

class SwitchView extends Controller
{
	function index()
	{
		$data = array();
		$data['message'] = 'こんちくわ!';

		$this->load->helper('url');
		$this->load->library('user_agent');

		if ($this->agent->is_mobile())
		{
			$this->load->view('switch_view/mobile', $data);
		}
		else
		{
			$this->load->view('switch_view/pc', $data);
		}
	}

	function _output($output)
	{
		if ($this->agent->is_mobile())
		{
			$output = mb_convert_encoding($output, 'SJIS', $this->config->item('charset'));
			header('Content-Type: text/html; charset=shift-jis;');
		}
		
		echo $output;
	}
}

?>

んで、PC用View


<html>
<head>
<link rel="stylesheet" type="text/css" href="<?=site_url()?>css/contact.css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CodeIgniter で表示切り替え</title>
</head>
<body>
<h1>PC版</h1>
<?=$message?>
</body>
</html>

そいで、モバイル用View文字コードは UTF-8。Shift_JIS で書いたり、meta にshift_jis を指定したりすると文字化けする。


<html>
<head>
<title>CodeIgniter で表示切り替え</title>
</head>
<body>
<h1>モバイル版</h1>
<?=$message?>
</body>
</html>

実行結果が見たい方は、Firefoxの拡張機能 User Agent Switcherなんかを使って、ユーザーエージェントで View 切り替えページにれっつアクセス!

テーマ:PHP - ジャンル:コンピュータ

CodeIgniter リクエスト値を内部文字コードに変換処理

PCサイトと携帯サイトを同じURLで運営してると、フォームで送信した場合、データの文字コードの問題が出てくると思います。それなら、統一してしましょうと頑張ってみた。

やり方は2通りあると思います。一つは、Inputライブラリの CI_Inputクラスを拡張する方法。もう一つは、コアファイルをいじることなくフレームワークの内部動作を変更する方法(フック)です。個人的には CI_Inputクラスをいじりたくないので、フックする方法で文字コード変換処理を実現させてみたいと思います。

まずは、application/config/config.php の設定値を変更。


$config['enable_hooks'] = TRUE;

続いて、application/config/hooks.php に以下のコードを追加。$hook['post_controller_constructor'] はコントローラがインスタンス化された直後で、メソッドの呼び出しが起こる前に呼ばれます。詳しくはフック - フレームワークコアの拡張で。


$hook['post_controller_constructor'] = array(
                                'class'    => 'ConvertEncode',
                                'function' => 'execute',
                                'filename' => 'ConvertEncode.php',
                                'filepath' => 'hooks'
                                );

んで、フックさせるクラスをapplication/hooks 内に設置します。


<?php
class ConvertEncode
{
	function execute()
	{
		$CI =& get_instance();
		$charset = $CI->config->item('charset');

		if ($CI->config->item('enable_query_strings')) $this->convert($_GET, $charset);
		$this->convert($_POST, $charset);
		$this->convert($_COOKIE, $charset);
	}


	function convert(&$data, $charset)
	{
		if (is_array($data))
		{
			foreach ($data as $key => $val)
			{
				if (is_array($val))
				{
					$this->convert($val, $charset);
				}
				else
				{
					$enc = mb_detect_encoding($val, "ASCII,JIS,UTF-8,EUC-JP,SJIS");
					$data[$key] = mb_convert_encoding($val, $charset, $enc);
				}
			}
		}

	}

}
?>

これでリクエスト値は application/config/config.php で設定された文字コードに変換されるはずです。多分。処理速度が気になる場合は、CI_Input クラスを拡張した方が良いかもしれません。

【“CodeIgniter リクエスト値を内部文字コードに変換処理”の続きを読む】

テーマ:PHP - ジャンル:コンピュータ

CodeIgniter Validation クラスの最大最小文字数チェックをマルチバイト対応化

デフォルトではマルチバイト対応してないので、自分で対応させてみた。やり方は簡単。Validation クラスを継承してマルチバイト対応に書き換える(オーバーライド)だけよん。

ただ、継承する場合は決まり事があるので注意してね。継承する自クラス名の頭に MY_ 、継承元の親クラス名の頭に CI_ を付けなきゃだめよ。あと、自クラスでコンストラクタを呼ぶ場合は、コンストラクタの中で親クラスのコンストラクタを呼び出しましょう。


<?php

class MY_Validation extends CI_Validation
{

	function min_length($str, $val)
	{
		$CI =& get_instance();

		if (preg_match("/[^0-9]/", $val))
		{
			return FALSE;
		}
	
		return (mb_strlen($str, $CI->config->item('charset')) < $val) ? FALSE : TRUE;
	}


	function max_length($str, $val)
	{
		$CI =& get_instance();

		if (preg_match("/[^0-9]/", $val))
		{
			return FALSE;
		}
		return (mb_strlen($str, $CI->config->item('charset')) > $val) ? FALSE : TRUE;
	}

}

?>

作成した継承クラス MY_Validation.php は、application/libraries フォルダ内に 放り込めば自動で読み込んでくれますわ。

テーマ:PHP - ジャンル:コンピュータ

CodeIgniter のビューで共通のヘッダーやらフッターを表示したい

色々試行錯誤してスマートにやる方法を見つけた。でもこれが正解かはわからないに。

まずは共通のヘッダーやらフッターやらを書いたクラス CommonView(common_view.php)を用意。


<?php
class CommonView
{
    function html_open($title)
    {
        echo '<html><head><title>'.$title.'</title></head><body>';
    }

    function html_close()
    {
        echo '</body></html>';
    }
}
?>

んで、コントローラーの中でメインのビューと共に呼び出す。


$this->load->view('common_view');
$this->load->view('index');

そして index ビューの中で、静的クラスとして呼び出す。


<?=CommonView::html_open('テスト')?>

<h1>テスト</h1>
<p>てすてす。てすてす。</p>

<?=CommonView::html_close()?>

こんな感じでしょうか。これで良いのかしらー。

テーマ:PHP - ジャンル:コンピュータ

CodeIgneter で メールフォームを作ってみるの巻

Codeigniter の基礎の基礎について分かったので、練習がてらにメールフォームを作ってみたわ。

まずはコントローラ部分


<?php

class Contact extends Controller
{

    function index()
    {
        // ヘルパ関数・ライブラリ呼び出し
        $this->load->helper(array('form', 'url'));
        $this->load->library('validation');


        // バリデーションルール設定
        $rules['email'] = "trim|required|valid_email|xss_clean";
        $rules['subject'] = "trim|required|max_length[20]|xss_clean";
        $rules['message'] = "trim|required|max_length[100]|xss_clean";

        $this->validation->set_rules($rules);


        // バリデーションエラー時のフィールド名設定
        // 詳しくは system/language/フォルダ名/validation_lang.php
        $fields['email'] = 'メールアドレス';
        $fields['subject'] = '件名';
        $fields['message'] = 'メッセージ';

        $this->validation->set_fields($fields);


        // エラーメッセージを囲うタグを設定(デフォルトはpタグ)
        $this->validation->set_error_delimiters(
                        '<div class="err">', '</div>');


        // 検証エラーまたは初回アクセス時
        if ($this->validation->run() == FALSE)
        {
            $this->load->view('contact/form');
        }
        // 検証OK
        else
        {

            // emailライブラリ呼び出し
            $this->load->library('email');

            // 文字コード
            $config['charset'] = 'utf-8';
            // 設定初期化
            $this->email->initialize($config);
    
            // 差出人
            $this->email->from(
                            $this->input->post('email'),
                            $this->input->post('email'));
            // 送り先(自分宛)
            $this->email->to('自分のアドレス');
            // 件名
            $this->email->subject($this->input->post('subject'));
            // メッセージ
            $this->email->message($this->input->post('message'));



            $data = array();

            // メール送信OK
            if (@$this->email->send())
            {
                $data['result_message'] = 
                            'メールは正しく送信されました。';
            }
            // メール送信エラー
            else
            {
                $data['result_message'] = 'メール送信エラー';

            }

            $this->load->view('contact/send_result', $data);


        }
    }

}


?>

そして問い合わせフォーム部分。site_url() は urlヘルパー関数、form_open()、form_close() は formヘルパー関数。$this->validation うんぬんは…ソース見れば分かると思う。


<html>
<head>
<link rel="stylesheet" type="text/css" href="<?=site_url()?>css/contact.css" />

<title>問い合わせ</title>
</head>
<body>
<h1>問い合わせ</h1>

<?php if ($this->validation->error_string):?>
<div id="err-box">
<?=$this->validation->error_string; ?>
</div>
<?php endif;?>

<p>CodeIgniter で作ったメールフォーム</p>

<?=form_open('contact')?>
<dl>
<dt>メールアドレス</dt>
<dd><?=$this->validation->email_error?><input type="text" name="email" value="<?=$this->validation->email?>" class="ipt-bg" /></dd>
<dt>件名</dt>
<dd><?=$this->validation->subject_error?><input type="text" name="subject" value="<?=$this->validation->subject?>" class="ipt-bg" /></dd>
<dt>メッセージ</dt>
<dd><?=$this->validation->message_error?><textarea name="message"><?=$this->validation->message?></textarea></dd>
</dl>
<input type="submit" value="送信" />
<?=form_close()?>


</body>
</html>

で、送信結果ビュー。anchor() は urlヘルパーの関数ですよ。


<html>
<head>
<link rel="stylesheet" type="text/css" href="<?=site_url()?>css/contact.css" />

<title>問い合わせ</title>
</head>
<body>
<h1>問い合わせ</h1>
<p><?=$result_message?></p>
<p><?=anchor('contact', 'もう一度'); ?></p>
</body>
</html>

これじゃあ説明足んねーよー。わかんねーよー。バーカバーカ。って方は、実際にメールフォームをいじって観察しましょう。メールは送信されないようにしてあるのでお気軽にどうぞ。

テーマ:PHP - ジャンル:コンピュータ

前のページ 次のページ