[[CodeIgniter]]

#norelated

#contents

* バリデーションとは? [#j89787b2]
ユーザー「入力値」の妥当性を、システム側で「検証」し、適切に処理すること。

//-----------------------------------------------------------------------------

* 参考リンク [#zd299faa]
-CodeIgniter ユーザガイド 日本語版 ? フォーム・バリデーション(検証) 	
http://codeigniter.jp/user_guide_ja/libraries/form_validation.html

- [[CodeIgniter Form]]
Formヘルパー(入力フォームの作成支援機能)の使い方

//-----------------------------------------------------------------------------

* バリデーションクラス [#pb3c50e5]
CodeIgniterで用意されているバリデーションクラスを利用して、ユーザーの入力値をチェックします。

** 処理の流れ [#ye260d06]
+ 入力ページ(フォーム)が表示されます。
+ ユーザーが、入力して送信します。
+ 間違ったデータが送信された場合や、必要項目が入力されていない場合、エラーメッセージを、入力したデータと一緒にフォームで再表示します。
+ 送信データが正しい形式になるまで、上記の処理を繰り返します。

データを受け取るページで、入力値のチェック処理を行います。
+ 必須入力のデータをチェックする。
+ データが、正しいデータ型か?、データが条件に合致するか?等をチェックする。
(ユーザー名が送信された場合、許可した文字だけになっているか?等)
+ セキュリティのためにデータをサニタイズする。
+ 必要であれば、前もってデータをフォーマットします。
(前後の余計な空白文字を除去する、等)
+ データベースに追加するデータを準備します。

** フォームバリデーション(検証)の実装 [#p381d849]
次の3つのファイルを用意します。

|ファイル|内容|h
| 入力ページのビュー | 入力フォームを設置したビューファイル |
| 結果ページのビュー | 送信が成功したときに、「成功」"メッセージを表示するビューファイル |
| コントローラー | 送信されたデータを受け取り、処理できるようにしたコントローラ内のメソッド |

*** 入力ページ [#v0313214]
入力フォームのビューファイルを用意する。
 applications/views/myform.php

#code(html){{
<html>
  <head>
    <title>マイフォーム</title>
  </head>
  <body>
    <?php echo validation_errors(); ?>
    <?php echo form_open('form'); ?>
      <h5>ユーザ名</h5>
      <input type="text" name="username" value="<?php echo set_value('username'); ?>" size="50" />
      <h5>パスワード</h5>
      <input type="text" name="password" value="<?php echo set_value('password'); ?>" size="50" />
      <h5>パスワードの確認</h5>
      <input type="text" name="passconf" value="<?php echo set_value('passconf'); ?>" size="50" />
      <h5>メールアドレス</h5>
      <input type="text" name="email" value="<?php echo set_value('email'); ?>" size="50" />
      <div><input type="submit" value="送信" /></div>
    </form>
  </body>
</html>
}}

*** 結果ページ [#s836a3a9]
バリデーションの結果を表示するビューファイルを用意する。
 applications/views/formsuccess.php

#code(html){{
<html>
  <head>
    <title>マイフォーム</title>
  </head>
  <body>
    <h3>フォームは正しく送信されました!</h3>
    <p><?php echo anchor('form', 'もう一度!'); ?></p>
  </body>
</html>
}}

*** コントローラー [#la094b9a]
入力ページを制御するコントローラーファイルを用意する。
 applications/controllers/form.php

#code(php){{
<?php

class Form extends CI_Controller {
	
	function index()
	{
		$this->load->helper(array('form', 'url'));
		$this->load->library('form_validation');

		$this->form_validation->set_rules('username', 'ユーザ名', 'required');
		$this->form_validation->set_rules('password', 'パスワード', 'required');
		$this->form_validation->set_rules('passconf', 'パスワードの確認', 'required');
		$this->form_validation->set_rules('email', 'メールアドレス', 'required');
				
		if ($this->form_validation->run() == FALSE)
		{
			$this->load->view('myform');
		}
		else
		{
			$this->load->view('formsuccess');
		}
	}
}
?>
}}

//-----------------------------------------------------------------------------

* 検証ルールを設定する [#ia22990b]
バリデーションクラスのset_rules()メソッドを使って検証ルールを設定します。
 $this->form_validation->set_rules();

** set_rules()メソッドの引数 [#c721c267]
set_rules()メソッドに、3つの引数を指定します。
| 引数 | 引数の順番 | 内容 |h
| フォーム名 |1番目| フォームの name 属性に指定した値 |
| フォームの表示名 |2番目| 「user」という入力フィールドの表示名として「名前」等 |
| フォームに設定する検証ルール |3番目| 'required', 'max_length[12]'等、CodeIgniterで用意されている値 |

-「フォームの表示名」は、エラーメッセージの表示で使われる。
-「検証ルール」は、CodeIgniterが用意してくれた検証ルールだけではなく、コールバック関数を自作することによって、ユーザーが指定した検証ルールを適用させることもできる。

** set_rules()メソッドの呼出し [#g2f14cff]
コントローラ (form.php) の中で、バリデーションクラスを初期化(ロード)した後、set_rules()メソッドを使います。

#code(php){{
$this->form_validation->set_rules('username', 'ユーザ名', 'required');
$this->form_validation->set_rules('password', 'パスワード', 'required');
$this->form_validation->set_rules('passconf', 'パスワードの確認', 'required');
$this->form_validation->set_rules('email', 'メールアドレス', 'required');
}}

- CodeIgniterでは、指定したフィールドにどれだけ多くのルールを適用してもかまいません。
- ルールは順番に続けて適用することができ、同時にデータを整形したり前処理を行ったりすることもできます。

** 配列を使った検証ルールの一括指定 [#u14d9672]
一回で全ての検証ルールを設定したい場合、set_rules()メソッドの引数を配列にします。
引数の配列は、検証ルール設定メソッドを通る配列の形式で記述しなければいけません。

#code(php){{
$config = array(
               array(
                     'field'   => 'username',
                     'label'   => 'ユーザ名',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'password',
                     'label'   => 'パスワード',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'passconf',
                     'label'   => 'パスワードの確認',
                     'rules'   => 'required'
                  ),   
               array(
                     'field'   => 'email',
                     'label'   => 'メールアドレス',
                     'rules'   => 'required'
                  )
            );

$this->form_validation->set_rules($config);
}}

** ルールの連結(カスケード) [#z53ea3c8]
set_rules()メソッドの、3番目の引数である「検証ルール」は、複数のルールを指定できます。
各ルールは「|」でつなげて記述します。

#code(php){{
$this->form_validation->set_rules('username', 'ユーザ名', 'required|min_length[5]|max_length[12]');
$this->form_validation->set_rules('password', 'パスワード', 'required|matches[passconf]');
$this->form_validation->set_rules('passconf', 'パスワードの確認', 'required');
$this->form_validation->set_rules('email', 'メールアドレス', 'required|valid_email');
}}

上記の例では、
+ username フィールドは、5文字より小さくてはだめで、12文字を超えてはいけません。
+ password フィールドは、パスワード確認フィールドと入力が一致しなければなりません。
+ email フィールドは、正しいメールアドレスの形式でなければなりません。
というルールを追加してします。

** データの整形 [#t427f45b]
バリデーションの機能は、データの整形をすることもできます。
たとえば、以下のように、ルールを追加することができます。

#code(php){{
$this->form_validation->set_rules('username', 'ユーザ名', 'trim|required|min_length[5]|max_length[12]|xss_clean');
$this->form_validation->set_rules('password', 'パスワード', 'trim|required|matches[passconf]|md5');
$this->form_validation->set_rules('passconf', 'パスワードの確認', 'trim|required');
$this->form_validation->set_rules('email', 'メールアドレス', 'trim|required|valid_email');
}}

上記の例では、
+ トリミング(文字列の先頭と末尾にある空白の除去)を行う
+ パスワードを MD5 に変換する
+ 悪意のあるデータを取り除く "xss_clean" 機能を通す
というルール(処理)を追加してします。

-データの整形を指定するルール名として、
htmlspecialchars、trim、MD5
などのような引数を1つだけとる&color(red){PHPの組込み関数};はどれでもルールとして使用することができます。

-もし入力エラーがあった場合、元のデータをフォームに表示させる必要があるため、検証が済んだ後に、データ整形をしたいのが普通の流れだと思います。
=データの整形は、使い方に注意!

//-----------------------------------------------------------------------------

* 独自の検証ルール [#b5a41915]
コールバックメソッドを作ると、独自の検証ルールを設定できます。
http://codeigniter.jp/user_guide_ja/libraries/form_validation.html#callbacks

** コールバック関数とは? [#jafad02e]
[[コールバック]]は、「他の関数に、引数として渡される関数」のことを「コールバック関数」といいます。
~
~

CodeIgniterのバリデーションクラスは、検証ルールを設定するset_rules()メソッドの第3引数によって、他のメソッド(=コールバックメソッド)を呼び出す仕組みになっており、いろいろな検証作業をさせることができます。
 system/libraries/Form_validation.php
のソースコードを見ると、仕組みの詳細が分かります。

+ CodeIgniterが、標準で用意している検証作業(のメソッド)
+ ユーザーが独自に定義できる検証作業(のメソッド)
が使えます。

以下は、ユーザーが独自に定義できる検証作業(=コールバックメソッドを自前で用意する方法)の説明になります。

** コールバック: ユーザ定義の検証メソッド [#l96a49ca]
ユーザ定義の検証メソッドへのコールバックが、CodeIgniterでサポートされています。
この機能を使えば、検証ルールを拡張することができます。

例えば、ユーザー名の登録において、固有の名前かどうかを調べるためにデータベースを参照する必要がある場合など、コールバックメソッドを作って調べることができます。
これは、次のような方法でできます。

+ 検証ルールで、「username」に適用するルールを次のように変更します。
#code(php){{
$this->form_validation->set_rules('username', 'ユーザ名', 'callback_username_check');
}}
+ 次に「username_check」という名前の新しいメソッドをコントローラに追加します。
#code(php){{
<?php

class Form extends CI_Controller {

    function index()
    {
        $this->load->helper(array('form', 'url'));
        $this->load->library('form_validation');

        $this->form_validation->set_rules('username', 'ユーザ名', 'callback_username_check');
        $this->form_validation->set_rules('password', 'パスワード', 'required');
        $this->form_validation->set_rules('passconf', 'パスワードの確認', 'required');
        $this->form_validation->set_rules('email', 'メールアドレス', 'required');

        if ($this->form_validation->run() == FALSE)
        {
            $this->load->view('myform');
        }
        else
        {
            $this->load->view('formsuccess');
        }
    }

    // callback method for original validation rules
    function username_check($str)
    {
        if ($str == 'test')
        {
            $this->form_validation->set_message('username_check', 'フィールド %s に、"test"は使えません');
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
}
?>
}}

set_rules()メソッドの第3引数で、自前で用意したコールバックメソッドを呼び出すには、「&color(red){callback_};」+「コールバックメソッド名」という値を指定すればOKと。

- set_rules()の第3引数で、「&color(red){callback_};username_check」と指定する。
- 「username_check」というメソッドが呼び出されて使われる。

CodeIgniterのバリデーションクラスで用意されている既存の検証ルールではチェックできない条件も、自前でコールバックメソッドを用意すればチェックできるようになります。

正規表現を使った細かいチェック等をやりたい場合に便利な機能ですね!
 例:郵便番号の形式「123-4567」に合致しているかチェックする等。

//-----------------------------------------------------------------------------

* 検証の実行 [#rbca80ac]
バリデーションクラスのrun()メソッドで、ユーザー入力値の検証を実行します。
 $this->form_validation->run();

run()メソッドは、ユーザー入力値の検証を実行し、
- 成功時(入力値が検証ルールに適合した場合)は &color(red){TRUE}; を返す。
- 失敗時(入力値が検証ルールに適合しなかった場合)は &color(red){FALSE}; を返す。

成功時は、入力値に基づいて、必要な処理を行う。
失敗時は、ユーザーに再入力させる → 入力フォームを再表示する。

** run()メソッドの引数 [#gee1fbbc]
run()メソッドは、検証ルールの「グループ名」を引数として渡せます。
検証ルールのグループ名とは、複数の検証ルールを配列の形(=グループ)で設定してある場合の、個別のルールの名前です。

*** (参考)検証ルールのセットを作る [#n4465db5]
http://codeigniter.jp/user_guide_ja/libraries/form_validation.html#savingtoconfig

-検証ルールは、上述のように、配列の形で指定できます。
-さらに、&color(red){複数の検証ルール};を、配列の形で指定して、呼び出すことができます。

コントローラーの記述例:
#code(php){{
$config = array(
    'signup' => array(
        array(
            'field' => 'username',
            'label' => 'ユーザ名',
            'rules' => 'required'
        ),
        array(
            'field' => 'password',
            'label' => 'パスワード',
            'rules' => 'required'
        ),
        array(
            'field' => 'passconf',
            'label' => 'パスワードの確認',
            'rules' => 'required'
        ),
        array(
            'field' => 'email',
            'label' => 'メールアドレス',
            'rules' => 'required'
        )
    ),
    'email' => array(
        array(
            'field' => 'emailaddress',
            'label' => 'メールアドレス',
            'rules' => 'required|valid_email'
        ),
        array(
            'field' => 'name',
            'label' => '名前',
            'rules' => 'required|alpha'
        ),
        array(
            'field' => 'title',
            'label' => 'タイトル',
            'rules' => 'required'
        ),
        array(
            'field' => 'message',
            'label' => 'メッセージ本文',
            'rules' => 'required'
        )
    )                          
);

// 特定のルールグループを呼び出す
// 特定のグループを呼び出すには run() メソッドにその名前を渡します。
// たとえば、 signup ルールを呼び出すにはこのようにします:
if ($this->form_validation->run('signup') == FALSE)
{
   $this->load->view('myform');
}
else
{
   $this->load->view('formsuccess');
}
}}

- 配列の検証ルールを、さらにグループ名をキーとする配列に入れます。
- run()メソッドに、検証ルールのグループ名(配列のキー)を渡します。
上記の例では、「signup」という検証ルールを呼び出しています。

//-----------------------------------------------------------------------------

* 入力フォームの再表示 [#k08dfe0b]

** エラーメッセージ表示 [#raa6d997]
[[Formヘルパー>CodeIgniter Form]]のvalidation_errors()関数を使って、入力値の検証結果(エラーメッセージ)を表示させることができます。
 validation_errors()

validation_errors()関数は、Formヘルパーをロードしないと使えないので注意!
 $this->load->helper('form');

validation_errors()関数は、バリデーションクラスのバリデータが返すエラーメッセージを取得して、出力します。
メッセージがなければ、何も出力しません。
&color(red){(注意:run()メソッドを実行して、検証した後じゃないと、バリデーションクラスからエラーメッセージを取得できません。)};

入力ページで、エラーメッセージを表示させる場所に、以下のように記述します。
#code(php){{
<?php echo validation_errors(); ?>
}}

*** (参考)Formヘルパーのvalidation_errors()関数 [#fe004d51]
validation_errors()は、以下の場所で定義されています。

ファイル:
 system/helpers/form_helper.php

関数定義:
#code(php){{
/**
 * Validation Error String
 *
 * Returns all the errors associated with a form submission.  This is a helper
 * function for the form validation class.
 *
 * @access	public
 * @param	string
 * @param	string
 * @return	string
 */
if ( ! function_exists('validation_errors'))
{
	function validation_errors($prefix = '', $suffix = '')
	{
		if (FALSE === ($OBJ =& _get_validation_object()))
		{
			return '';
		}

		return $OBJ->error_string($prefix, $suffix);
	}
}
}}

** 入力値の再表示 [#scb48f1f]
[[Formヘルパー>CodeIgniter Form]]のset_value()関数を使って、ユーザーの入力値を、入力ページで、再表示させることができます。
 set_value()

set_value()関数は、Formヘルパーをロードしないと使えないので注意!
 $this->load->helper('form');

set_value()関数は、バリデーションクラスのバリデータが返すユーザーの入力値を取得して、出力します。
元々の入力値がなければ、何も出力しません。
&color(red){(注意:run()メソッドを実行して、検証した後じゃないと、バリデーションクラスから入力値を取得できません。)};

入力ページで、ユーザーの入力値を再表示させる場所に、以下のように記述します。
#code(php){{
<?php echo set_value('username'); ?>
}}

具体的には、
- フォームのvalueに、set_value()関数を入れます。
- set_value()関数の引数には、各フォームのnameを入れます。

#code(html){{
<h5>ユーザ名</h5>
<input type="text" name="username" value="<?php echo set_value('username'); ?>" size="50" />
}}

*** (参考)Formヘルパーのset_value()関数 [#sb4b09fd]
set_value()は、以下の場所で定義されています。

ファイル:
 system/helpers/form_helper.php

関数定義:
#code(php){{
/**
 * Form Value
 *
 * Grabs a value from the POST array for the specified field so you can
 * re-populate an input field or textarea.  If Form Validation
 * is active it retrieves the info from the validation class
 *
 * @access	public
 * @param	string
 * @return	mixed
 */
if ( ! function_exists('set_value'))
{
	function set_value($field = '', $default = '')
	{
		if (FALSE === ($OBJ =& _get_validation_object()))
		{
			if ( ! isset($_POST[$field]))
			{
				return $default;
			}

			return form_prep($_POST[$field], $field);
		}

		return form_prep($OBJ->set_value($field, $default), $field);
	}
}
}}

*** 配列を使うときの注意点 [#ka2dbb25]
フォームの名前には、配列を使うことができます。
フォームの名前に配列を使う場合、set_value()関数の引数も、配列の形で指定します。

#code(html){{
<input type="text" name="colors[]" value="<?php echo set_value('colors[]'); ?>" size="50" />
}}

※詳しくは、CodeIgniterのマニュアルを見てください。\(手抜き)/
http://codeigniter.jp/user_guide_ja/libraries/form_validation.html#arraysasfields

//-----------------------------------------------------------------------------

* まとめ [#u16f85f0]
- CodeIgniterは、ユーザー入力値のチェックが簡単にできる。
- Formバリデーション(検証)クラスとFormヘルパーをロードして使う。
 $this->load->library('form_validation');
 $this->load->helper('form');
- まずは、普通に入力ページと結果ページ(入力の確認をするページ等)を用意する。
- 検証ルールを作る。
- 検証した結果で、処理を分岐させる。
-- 成功した場合は、必要な処理を行う。
-- 失敗した場合は、ユーザーに再入力させる。 
--- 再入力のために、入力ページを再表示するとき、Formヘルパーのset_value()関数やvalidation_errors()関数が使える。

CodeIgniterは、便利だな~!(・∀・)

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS