CodeIgniter ユーザガイド 日本語版 Version 1.6.3


フォーム・バリデーション(検証)

CodeIgniterのデータ検証アプローチの説明をする前に、想定するシナリオについて述べておきます:

  1. フォームが表示されます。
  2. 入力して送信します。
  3. 間違ったデータが送信された場合、あるいは、必要項目が入力されていない場合、それらの問題についてのエラーメッセージを、入力したデータと一緒に、フォームで再表示します。
  4. 送信データが正しい形式になるまで、上記の処理を繰り返します。

最後にデータを受け取るところで、そのスクリプトでは次のようなことが必要になります:

  1. 必須入力のデータをチェックする。
  2. データが正しいデータ型か、また、データが条件に合致するかをチェックする。(たとえば、ユーザ名が送信された場合、 許可した文字だけになっているかを検証する必要があります。また、最小文字数以上で、最大文字数以下になているかの検証もします。 ユーザ名は、既に存在しているユーザ名と同じでなく、予約語と同じであってはならない。など)
  3. セキュリティのためにデータをサニタイズします [ 訳注: サニタイズとは無害化のこと。一般には、XSSやSQLインジェクションなどに使用される文字をフィルタリングしたりすることを指します。 ] 。
  4. 必要であれば、前もってデータをフォーマットします(前後のスペースをとる?HTMLにするか? など)。
  5. データベースに追加するため、データを準備します。

上で挙げたプロセスには何ら複雑なものはありませんが、たいてい大量のコードが必要になり、 エラーメッセージを表示させるために、フォームHTMLの中に、さまざまな制御構造が書かれることになります。 フォームの検証は、難しくなくつくれますが、実装するのはいつも面倒で退屈です。

CodeIgniter では、書く必要があるコードを最低限にとどめる包括的なバリデーション(検証)フレームワークが提供されています。 また、このフレームワークを使うと、HTMLフォームから制御構造を取り除くことができ、コードをわかりやすく、メンテナンスしやすいようにすることができます。

概観

CodeIgniter のフォーム・バリデーション(検証)を実装するには、次の3つが必要になります:

  1. フォームを設置したビューファイルを用意します。
  2. 送信が成功したときに、"成功" メッセージを表示する ビューファイルを用意します。
  3. コントローラ内のメソッドをデータを受け取れるようにし、送信されたデータを処理できるようにします。

例としてメンバー登録フォームを使って、これら3つを作成してみましょう。

入力フォーム

テキストエディタを使って、myform.php という名前のフォームを作ってください。その中に、次のコードを書いて applications/views/ フォルダの中に保存します:

成功ページ

テキストエディタを使って、formsuccess.php という名前のフォームを作ってください。 その中に、次のコードを書いて applications/views/ フォルダの中に保存します:

コントローラ

テキストエディタを使って、form.php という名前のコントローラを作ってください。 その中に、次のコードを書いて applications/controllers/ フォルダの中に保存します:

動かしてみよう !

作ったフォームを動かすため、次のうようなURLでサイトを訪問してください:

example.com/index.php/form/

フォームに送信すると、単にフォームが更新されるだけに見えます。これは、まだ検証ルールを一つも設定していないからです。 検証ルールについては、もうすぐわかります。

解説

上の例のページについていくつか気づいたことがあると思います:

フォーム (myform.php) は、次の2つの例外を除いて、スタンダードなwebフォームだといえます:

  1. fromタグを開始するのに Formヘルパ を使っています。技術的には、これは必ずしも必要ではありません。 通常のHTMLを使ってformを作成することもできます。しかし、このヘルパを使うと、 formタグのaction属性に指定するURLを設定ファイルのURLにもとづいて生成してくれるという利点があります。 これにより、URLを変更した時のアプリケーションの移植性と柔軟性が高まります。
  2. フォームの先頭に、次のような変数があるのに気がついたと思います: <?php echo $this->validation->error_string; ?>

    この変数は、バリデータが返すエラーメッセージを表示します。メッセージがなければ、何も表示しません。

コントローラ (form.php) には index() というメソッドがあります。このメソッドは、 バリデーションクラスを初期化しビューファイルで使えるように FormヘルパURLヘルパ をロードします。 また、検証処理も実行します。検証が成功したかどうかにより、 フォームのページか成功ページかどちらかを表示します。

ここでは、まだバリデーションクラスになにも検証しないように設定しています。バリデーションクラスは、デフォルトでは、"false" (ブール値のFLASE)を返します。run() メソッドは、一つも失敗せずにユーザが指定したルールに適合する場合にのみ "true" を返します。

検証ルールを設定する

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

コントローラ (form.php) の中のバリデーションクラスを初期化(ロード)したすぐ下のところに、このコードを追加してください:

$rules['username'] = "required";
$rules['password'] = "required";
$rules['passconf'] = "required";
$rules['email'] = "required";

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

コントローラは次のようになっているはずです:

ここで、フィールドを空にしたまま送信すると、エラーメッセージが表示されます。 すべてのフィールドを埋めて送信すると、成功ページが表示されます。

Note: フォームのフィールドは、エラーの時に入力したデータが復元されません。 検証ルールに説明した後、すぐそれについて説明します。

エラーメッセージを囲む文字の変更

初期状態では、システムは、段落タグ (<p>) で表示される各メッセージを囲みます。 次のコードをコントローラに書くことで、囲み文字を簡単に変更できます:

$this->validation->set_error_delimiters('<div class="error">', '</div>');

この例では、div タグを使うよう切り替えています。

ルールの連結(カスケード)

CodeIgniter では、複数のルールを互いにパイプすること [ 訳注: パイプとは、処理結果を後続する処理に渡しながら処理を連結していくこと。UNIXでパイプを作成するときは、シェルでバーティカルバー( "|" )で連結する。 ] ができます。では、やってみましょう。ルールの配列を次のように変更してみてください:

$rules['username'] = "required|min_length[5]|max_length[12]";
$rules['password'] = "required|matches[passconf]";
$rules['passconf'] = "required";
$rules['email'] = "required|valid_email";

上のコードでは次のことが要求されます:

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

データを入力して、やってみてください!

Note: ルールリファレンスにあるように、多くの検証ルールがあります。

データの整形

バリデーションの機能は、上で使ったようなものに加え、様々な方法で、データの整形をすることもできます。 たとえば、以下のように、ルールをセットすることができます:

$rules['username'] = "trim|required|min_length[5]|max_length[12]|xss_clean";
$rules['password'] = "trim|required|matches[passconf]|md5";
$rules['passconf'] = "trim|required";
$rules['email'] = "trim|required|valid_email";

上の例では、フィールドを "トリミング" し、パスワードをMD5に変換し、 悪意のあるデータを取り除く "xss_clean" 機能を通します。

htmlspecialcharstrimMD5 などのような引数を一つだけとるPHPの組み込み関数は どれでもルールとして使用することができます。

Note: もしエラーがあった場合、もとのデータをフォームに表示させるため、 検証ルールの後に整形機能を使いたいのが通常のケースだと思います。

コールバック: ユーザ定義の検証メソッド

ユーザ定義の検証メソッドへのコールバックがシステムでサポートされています。 これを使えば、それぞれのニーズに合わせるため検証クラスを拡張することができます。たとえば、 選択したユーザが固有の名前かどうかを調べるためデータベースクエリを実行する必要があるとき、それを行うコールバックメソッドを作成できます。簡単なサンプルを作成してみましょう。

コントローラで、"username" ルールを次のように変更します:

$rules['username'] = "callback_username_check";

次に username_check という名前の新しいメソッドをコントローラに追加します。コントローラは以下のようになっているはずです:

フォームを再読み込みして、ユーザ名に "test" と入力して送信します。 フォームフィールドのデータがコールバックメソッドに渡され処理されたのがわかります。

コールバックを呼び出すには、あるルールに従ってメソッド名を指定します。そのルールとは、"callback_" というプリフィックスをメソッド名に付け加えるというものです。

エラーメッセージは、$this->validation->set_message メソッドを使ってセットされています。 メッセージのキー (第1引数) はメソッド名と一致させる必要があるというのを覚えておいてください。

Note: メッセージを同様にセットすれば、どんなルールに対しても、ユーザ定義のエラーメッセージを適用することができます。 たとえば、"required" ルールのメッセージを変更するには、次のようにします:

$this->validation->set_message('required', 'ここにカスタムメッセージ');

フォームの再表示

これまでのところ、エラーに対処してきただけでしたが、送信されたデータをフォームで再表示する時がやってきました。フォームの再表示はルールのときと同じように行うことができます。 次のコードをコントローラのルールを書いたところのすぐ下に追加してください:

$fields['username'] = 'ユーザ名';
$fields['password'] = 'パスワード';
$fields['passconf'] = 'パスワードの確認';
$fields['email'] = 'メールアドレス';

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

配列の添字は、フォームフィールドの実際の名前になり、値は、エラーメッセージで表示させたい そのフィールドのフルネームになります。

コントローラの中の index メソッド は次のようになります:

次にビューファイルの myform.php を開き、各フィールドの value 属性をフィールド名と関連付けられたオブジェクト名に変更します:

ここで、フォームを再読み込みし、エラーになるようなデータを送信します。 フォームフィールドには入力したデータが再表示され、エラーメッセージには、もっと適切なフィールド名が表示されるはずです。

個別にエラーを表示する

リストとしてではなく、各フォームフィールドのところでエラーメッセージを表示させたいときは、フォームを次のように変更できます:

エラーがないときは何も表示されません。エラーがあるときは、指定した文字(デフォルトでは<p>タグ) で囲まれたエラーが表示されます。

Note: このようにエラーを表示するには、前述の $this->validation->set_fields メソッドを使って、フィールドをセットする必要があるのを覚えておいてください。エラーはフィールド名の後ろに "_error" を付けた変数に変換されます。たとえば、"username" のエラーは次のような変数で利用可能です:
$this->validation->username_error.

ルールリファレンス

次のリストは、使用可能なすべての組み込みのルールです:

ルール パラメータ 説明
required なし フォームのデータが空のときに FALSE を返します。  
matches あり フォームのデータが他のフィールドの入力データと一致しないときに FALSE を返します。 matches[form_item]
min_length あり フォームのデータが指定したサイズよりも文字数が短いときに FALSE を返します。 min_length[6]
max_length あり フォームのデータが指定したサイズよりも文字数が長いときに FALSE を返します。 max_length[12]
exact_length あり フォームのデータが特定の長さでないときに FALSE を返します。 exact_length[8]
alpha なし フォームのデータがアルファベットでない文字を含むときに FALSE を返します。  
alpha_numeric なし フォームのデータが英数字でない文字を含むときに FALSE を返します。  
alpha_dash なし フォームのデータが英数字、アンダースコア("_")、ダッシュ("-") のいずれでないものを含むときに FALSE を返します。  
numeric なし フォームのデータが数字でないときに FALSE を返します。  
integer なし フォームのデータが整数以外の場合 FALSE を返します。  
valid_email なし フォームのデータがemailアドレスとして正しくないとき FALSE を返します。  
valid_emails なし コンマで区切られたリストのひとつでもメールアドレスとして正しくないとき FALSE を返します。  
valid_ip なし 渡されたIPが正しい形式でないときに FALSE を返します。  
valid_base64 なし 渡された文字列が正しい Base64 形式でないとき FALSE を返します。  

Note: また、これらのルールは、ふつうのメソッドとしても呼び出すことができます。例:

$this->validation->required($string);

Note: 引数を一つだけとるPHPの組み込み関数も使用できます。

整形処理のリファレンス

次のリストは、使用可能な整形メソッドのリストです:

名前 パラメータ 説明
xss_clean なし XSS フィルタリングメソッドを通過させます。XSSフィルタリングメソッドについては、入力クラスのページをご覧ください。
prep_for_form なし HTMLデータをフォームフィールドで崩れずに表示させるよう、HTML特殊文字を変換します。
prep_url なし もし、ない場合は、"http://" をURLに追加します。
strip_image_tags なし イメージへのURLをそのままにして、イメージタグからHTMLを取り除きます。
encode_php_tags なし PHP タグをHTMLエンティティに変換します[ 訳注: たとえば、"<?" を "&lt;?" に変換 ]。

Note: また、 trimhtmlspecialcharsurldecode などの 引数を一つだけとるPHPの組み込み関数をどれでも使用することができます。

ユーザ定義のエラーメッセージの設定

もともとのエラーメッセージは、次の言語ファイルの中にあります: language/english/validation_lang.php

ユーザ定義のメッセージを表示するには、このファイルを編集するか、または、次のメソッドを利用します:

$this->validation->set_message('rule', 'Error Message');

ここでの rule は特定のルール名になり、Error Message は表示したいテキストになります。

選択メニュー・ラジオボタン・チェックボックスの取り扱い

選択メニュー、ラジオボタン、チェックボックスを利用しているとき、エラーの時にそれらの選択状態を復元したい場合があります。 これをするのを支援するため、バリデーションクラスには、3つの機能が用意されています:

set_select()

選択されたメニュー項目を表示できます。 第1引数は、選択メニューの名前で、第2引数には、各項目の value 属性に設定した値を指定する必要があります。 例:

<select name="myselect">
<option value="one" <?php echo $this->validation->set_select('myselect', 'one'); ?> >One</option>
<option value="two" <?php echo $this->validation->set_select('myselect', 'two'); ?> >Two</option>
<option value="three" <?php echo $this->validation->set_select('myselect', 'three'); ?> >Three</option>
</select>

set_checkbox()

送信されたチェックボックスの状態を表示できます。第1引数は、チェックボックスの名前で、第2引数には、 各項目の value 属性に設定した値を指定する必要があります。例:

<input type="checkbox" name="mycheck" value="1" <?php echo $this->validation->set_checkbox('mycheck', '1'); ?> />

set_radio()

送信されたラジオボタンの状態を表示できます。第1引数は、ラジオボタンの名前で、第2引数には、 各項目の value 属性に設定した値を指定する必要があります。例:

<input type="radio" name="myradio" value="1" <?php echo $this->validation->set_radio('myradio', '1'); ?> />