CodeIgniter3+Bootstrap4でForm入力を前回に引き続きやります。
今回は、前回の画面に以下を追加します。
- 入力テキストに対するチェックを行う
- エラーメッセージの変数名を人間用に翻訳する
入力画面イメージのサンプルチェック仕様
まず、入力画面のイメージです。
やることは、シンプルに「ユーザID」と「パスワード」を入力して、それぞれ、以下のルールに一致しているかをチェックします。
- ユーザID :必須入力 と 文字種(半角英数字のみ)
- パスワード:必須入力 と 文字種(半角英数字のみ)と 文字数(8~20)
入力テキストに対するチェックを行う
後ろのコントローラクラスで参照する名前を確認するために、VIEW(入力画面)の入力に使うinputタグだけ抜き出しています。
ユーザID部分が「name="input-id"」で、パスワード部分が「name="input-password"」です。
<input type="text" class="form-control" id="input-id" name="input-id" placeholder="ユーザID(半角)を入力"> <input type="password" class="form-control" id="input-password" name="input-password" placeholder="パスワード">
入力に対してチェック(バリデーション)を行うには、コントローラクラスで「$this->form_validation->set_rules」を使って、チェックルールを指定します。
ひとつの項目に対して、複数のルールを指定する時は「|」でつなぎます。
例えば。
ユーザIDの場合。
必須入力(required) と 文字種正規表現判定(regex_match)の2つを同時にしているするのでこんな感じです。
$this->form_validation->set_rules('input-id', 'ユーザID', 'required|regex_match[/^[0-9a-zA-Z]+$/]' );
パスワードの場合。
必須入力(required) と 文字種(alpha_numeric)と 文字数(min_lengthとmax_length)を同時に指定するので、こんな感じ。
$this->form_validation->set_rules('input-password', 'パスワード', 'required|alpha_numeric|min_length[8]|max_length[20]' );
まあ、わかりやすくはあります。
なお。
半角英数字のみのチェックは、「alpha_numeric」という組み込みのものを使う方法と「regex_matchに正規表現(^[0-9a-zA-Z]+$)で指定する」方法の2通り書いてますが、どっちでもチェックは同じです。
あと、ソースを書く時の注意点がひとつ。
複数条件を連結する場合に
'required|alpha_numeric|min_length[8]|max_length[20]'
みたいに「|」と次の単語の間に空間をあけない書き方がいいです。
ソースの視認性を気にして以下のように書いても、動きますが・・。
'required|
alpha_numeric|
min_length[8]|
max_length[20]'
2番目以降のパラメータでエラーになった時に、メッセージが正しく表示されなくなる(適切なメッセージが見つからないとか)場合があります。
CodeIgniterには、上記以外にもいろいろ組み込みチェックが用意されてます。
主なものは、こんな感じです。
URLとかemailとか、正規表現で書くとややこしいものがあるのは有難いです。
regex_matchで正規表現を指定することで拡張もできますしね。
ルール | Parameter | 説明 | 例 |
---|---|---|---|
required | No | 空き要素の場合はFALSE | |
matches | Yes | formの要素が一致しない時はFALSE | matches[form_item] |
regex_match | Yes | 正規表現で指定したパターンに一致しない場合はFALSE | regex_match[/regex/] |
min_length | Yes | 指定する文字数より少ない場合はFALSE。 | min_length[3] |
max_length | Yes | 指定する文字数を超えた場合はFALSE。 | max_length[12] |
exact_length | Yes | 指定する文字数と一致しない場合はFALSE | exact_length[8] |
greater_than | Yes | 指定した値よりも(数字的に)等しいもしくは小さいか、数字でない時にFALSE 。 | greater_than[8] |
greater_than_equal_to | Yes | 指定した値よりも(数字的に)小さいか、数字でない時にFALSE 。 | greater_than_equal_to[8] |
less_than | Yes | 指定した値よりも(数字的に)等しいもしくは大きいか、数字でない時にFALSE 。 | less_than[8] |
less_than_equal_to | Yes | 指定した値よりも(数字的に)大きいか、数字でない時にFALSE 。 | less_than_equal_to[8] |
alpha | No | アルファベット以外の文字を含む場合、FALSE。 | alpha |
alpha_numeric | No | アルファベット・数字以外の文字を含む場合、FALSE。 | alpha_numeric |
alpha_numeric_spaces | No | アルファベット・数字・空白(半角)以外の文字を含む場合、FALSE。 | alpha_numeric_spaces |
alpha_dash | No | アルファベット、下線、dashesの以外の時にFALSE。 数字を含む場合はFALSE。 | alpha_dash |
numeric | No | 数字以外の文字を含む場合FALSE。 | numeric |
integer | No | 整数以外の数字・文字列の場合はFALSE。 | integer |
decimal | No | 小数点を含む数字以外の場合は、FALSE。 | decimal |
is_natural | No | 自然数以外の場合は、FALSE。 0, 1, 2, 3, etc. | is_natural |
is_natural_no_zero | No | 0を除く自然数の場合以外の場合は、FALSE。 | is_natural_no_zero |
valid_url | No | URL以外の値の場合は、FALSE。 | valid_url |
valid_email | No | email以外の値の場合は、FALSE。 | valid_email |
valid_emails | No | コンマを挟んだ複数のemail以外の値の場合は、FALSE。 | valid_emails |
valid_ip | No | IPアドレス以外の場合は、FALSE。 ‘ipv4’ or ‘ipv6’ の形式をサポートしています。 | valid_ip |
valid_base64 | No | Base64の形式以外の場合は、FALSE。 | valid_base64 |
エラーメッセージの変数名を人間用に翻訳する
今回は、各項目ごとにエラーメッセージを表示するようにしてみます。
エラーメッセージを上記のように表示する場合のPHPソースは。
<div class="form-group row my-4"> <label for="inputId" class="col-sm-2 col-form-label">ユーザID</label> <div class="col-sm-10"> <input type="text" class="form-control" id="input-id" name="input-id" placeholder="ユーザID(半角)を入力"> </div> <div class="col-sm-2"></div> <div class="col-sm-10 text-danger"> <?php echo form_error('input-id'); ?> </div> </div> <div class="form-group row my-4"> <label for="inputPassword" class="col-sm-2 col-form-label">パスワード</label> <div class="col-sm-10"> <input type="password" class="form-control" id="input-password" name="input-password" placeholder="パスワード"> <small id="passwordHelpBlock" class="form-text text-muted">パスワードは、文字と数字で8~20文字です。空白、記号、特殊文字、絵文字を含むことはできません。</small> </div> <div class="col-sm-2"></div> <div class="col-sm-10 text-danger"> <?php echo form_error('input-password'); ?> </div> </div>
エラーメッセージを項目ごとに表示する時は「 form_error('input-password')」のように、form_errorを使います。
各チェックに対応するエラーメッセージは言語ファイル「form_validation_lang.php」(application/languageの下)にあります。
例えば、min_lengthなら今のようにメッセージが用意されてます。
$lang['form_validation_min_length'] = '{field}欄は{param}文字以上、でなければいけません';
まず、 {param}には「min_length[5]」の場合だと「5」がはいります。
あと、 {field} タグには、set_rulesの第二パラメータの指定した名称がはいります。
下記例だと「ユーザID」がはいります。
$this->form_validation->set_rules('input-id', 'ユーザID', 'required|regex_match[/^[0-9a-zA-Z]+$/]' );
でも 、上記みたいにダイレクトに日本語を書いていると、ちょっとベタすぎます。
やっぱり、他のメッセージ同様に言語ファイルで多言語対応はしておきます。
まず、言語ファイルを用意します。
日本語の場合なら、application/language/japaneseの下に適当な名前で言語ファイルを作ります。
今回は「my_lang.php」という名前にします。
<?php defined('BASEPATH') OR exit('No direct script access allowed'); $lang['input-id'] = "ユーザID"; $lang['input-password'] = "パスワード"; ?>
この言語ファイルを用意したら、 コントローラクラスを以下のように変更します。
$this->lang->load('my_lang'); $this->form_validation->set_rules('input-id', 'lang:input-id', 'required|regex_match[/^[0-9a-zA-Z]+$/]' ); $this->form_validation->set_rules('input-password', 'lang:input-password', 'required|alpha_numeric|min_length[8]|max_length[20]' );
補足すると。
my_lang.phpをロードして使えるようにするのは、こんな感じ。
$this->lang->load('my_lang');
ロードした辞書ファイルから名称を持ってくるには、第二パラメータで「lang:」を使います。
例えば、「input-id」で言語ファイルから登録したメッセージを引く時は
lang:input-id
てな感じです。
これで、多言語対応もできました。
とりあえず、今回はこんなとこで。
最後に全体のソースです
まず、コントローラクラスから。
<?php defined('BASEPATH') or exit('No direct script access allowed'); class Demos extends CI_Controller { public function __construct() { parent::__construct(); $this->load->helper('url'); $this->load->helper('html'); } public function inpv() { $this->load->helper('form'); $this->load->library('form_validation'); $this->lang->load('my_lang'); $this->form_validation->set_rules('input-id', 'lang:input-id', 'required|regex_match[/^[0-9a-zA-Z]+$/]' ); $this->form_validation->set_rules('input-password', 'lang:input-password', 'required|alpha_numeric|min_length[8]|max_length[20]' ); $data['title'] = "formサンプル"; $data['id'] = $this->input->post('input-id'); $data['pass'] = $this->input->post('input-password'); if ($this->form_validation->run() === FALSE) { if (! file_exists(APPPATH . 'views/demos/inpvbody.php')) { show_404(); } $data['msg'] = "とりあえずIDとパスワードを入力するサンプル"; $this->load->view('templates/header', $data); $this->load->view('demos/inpvbody.php', $data); $this->load->view('templates/footer', $data); } else { if (! file_exists(APPPATH . 'views/demos/success_vbody.php')) { show_404(); } $data['msg'] = "入力を正常に受け取りました"; $this->load->view('templates/header', $data); $this->load->view('demos/success_vbody.php', $data); $this->load->view('templates/footer', $data); } } } ?>
入力画面のVIEW「inpvbody.php」です。
<div class="row"> <div class="col text-center"> <h3><?php echo $msg; ?></h3> </div> </div> <?php echo form_open('Demos/inpv'); ?> <div class="form-group row my-4"> <label for="inputId" class="col-sm-2 col-form-label">ユーザID</label> <div class="col-sm-10"> <input type="text" class="form-control" id="input-id" name="input-id" placeholder="ユーザID(半角)を入力"> </div> <div class="col-sm-2"></div> <div class="col-sm-10 text-danger"> <?php echo form_error('input-id'); ?> </div> </div> <div class="form-group row my-4"> <label for="inputPassword" class="col-sm-2 col-form-label">パスワード</label> <div class="col-sm-10"> <input type="password" class="form-control" id="input-password" name="input-password" placeholder="パスワード"> <small id="passwordHelpBlock" class="form-text text-muted">パスワードは、文字と数字で8~20文字です。空白、記号、特殊文字、絵文字を含むことはできません。</small> </div> <div class="col-sm-2"></div> <div class="col-sm-10 text-danger"> <?php echo form_error('input-password'); ?> </div> </div> <div class="form-group row my-4"> <div class="offset-sm-2 col-sm-10"> <button type="submit" class="btn btn-primary">実行する</button> </div> </div> </form>
入力OKの結果のVIEW「success_vbody.php」です。
<div class="row"> <div class="col text-center my-4"> <h2><?php echo $msg; ?></h2> </div> </div> <div class="row"> <div class="col text-center my-2"> <h2>入力されたIDは「<?php echo $id; ?>」です。 </h2> </div> </div> <div class="row"> <div class="col text-center my-2"> <h2>入力されたパスワードは「<?php echo $pass; ?>」です。 </h2> </div> </div> <div class="row"> <div class="col my-2 text-center"> <?php echo img('images/sample02.jpg'); ?> </div> </div>
なお、例によって、ヘダーとフッターの部分は以下の記事で書いたテンプレートの使いまわしです。
ではでは。