QA@IT

[Codeigniter] バリデーション設定が外部ファイルにできない

3795 PV

お世話になります。Codeigniter3で、バリデーション処理を実装しているのですが、外部ファイルにした設定を読み込んでくれません。。
ソースを追ったところ、そもそもできないのでは?と思い始め、質問させていただきました。

■コントローラ

class Book extends My_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->library('form_validation');
    }
・・・
    if($this->form_validation->run('inquiry') == FALSE){
        // code
    }

■外部に切り出したバリデーション定義ファイル

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$config = array(
    'inquiry' => array(
            array(
                'field' => 'card_no',
                'label' => 'カード番号',
                'rules' => 'required|max_length[12]'
            ),
・・・

■Form_Validationのソース

# system/libraries/Form_Validation.php
public function __construct($rules = array())   # $this->load->library('form_validation'); のタイミングで呼ばれる
{
・・・
    $this->_config_rules = $rules;              # $rulesは空なので$this->_config_rulesも空。


public function run($group = '')                # $groupには'inquiry'が入る
{
・・・
    if (count($this->_field_data) === 0)    # $this->_field_dataは0
    {
        if (count($this->_config_rules) === 0)  # $this->_config_rulesは空なのでここでFALSEでバリデーション失敗
        {
            return FALSE;
        }

ここ や他のサイトを見ても、大筋上記のような書き方をしていると思うのですが、具体的にどこで外部ファイルを呼んでいるのかわかりません。。

ご教授いただければ幸いです。
よろしくお願いします。

回答

今 3.0.3で試してみましたが可能です。
(Codeigniterは初めてなので命名とか変な部分があった場合はごめんなさい)

提示の公式ページ にある通り、

To store your validation rules, simply create a file named form_validation.php in your application/config/ folder.

外部バリデーション定義は application/config/form_validation.php を作成し、そこに記載します。

run()の引数に、定義したconfigの配列の名前を指定します。
コードが一部なのであったいるかわかりませんが、名前が 'scan'となっているので $this->form_validation->run('scan') とすべきなのかもしれません。

簡単なサンプル

view

入力画面として以下のView

application/views/name_form.php

<html><head>
    <title>QA@it 9721</title>
    <style>
        span { display:inline-block; width: 6em }
        .form-input { display:flex; flex-direction: column; }
    </style>
</head>
<body>
<?php echo validation_errors(); ?>
<?php echo form_open('myvalidate'); ?>
<div class="form-input" >
    <div>
        <span>ユーザ名</span><input type="text" name="username"/>
    </div>
    <div>
        <span>ニックネーム</span><input type="text" name="nickname" />
    </div>
    <div>
        <input type="submit" value="送る" />
    </div>
</div>
</form>
</body></html>

入力完了画面として以下のviewを用意します。

application/views/success_message.php

<html><head>
    <title></title>
</head>
<body>
sucess.
</body></html>

コントローラ

そのコントローラとして以下を作成します。

application/controllers/MyValidate.php

<?php

class MyValidate extends CI_Controller {
    public function __construct(){
        parent::__construct();

    }

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

        // ここではrunに引数を与えていません。
        if($this->form_validation->run() === false){ 
            $this->load->view('name_form');
        }else{
            $this->load->view('success_message');
        }
    }
}

form_validationファイル

外部の検証定義ファイルを作成します。
まずは簡単のために、名前を付けないバージョンです。

深さが2つの arrayで定義します。

application/config/form_validation.php

<?php
$config = array(
    array(
        'field' => 'username',
        'label' => 'ユーザー名',
        'rules' => 'required|min_length[4]|max_length[10]'
    ),
    array(
        'field' => 'nickname',
        'label' => 'ニックネーム',
        'rules' => 'required'
    )
);

Your validation rule file will be loaded automatically and used when you call the run() method.

このファイルは自動的に読み込まれ、run() を呼ぶと利用されます。

入力に問題があればこんな感じで検証されます。
(アプリケーションルート /index.php/myvalidate)

qait9721-1.PNG

複数のviewで使い分けたい

ところで、これだと 1つの定義しか書けません。
そこで、このarrayに名前を付けて、その名前をrunに渡すようにする事、複数の定義を使い分けることができます(多分)。

form_validationファイルを 以下の様に修正します。
arrayのネストが一つ増えている(深さが 3になった)事に注意してください。

application/config/form_validation.php

<?php
$config =
    array(
        // 名前を付けた
        'enter_name' => array(
            array(
                'field' => 'username',
                'label' => 'ユーザー名',
                'rules' => 'required|min_length[4]|max_length[10]'
            ),
            array(
                'field' => 'nickname',
                'label' => 'ニックネーム',
                'rules' => 'required'
            )
        ),
        // 別の定義
        'login' => array(
            array(
                'field' => 'password',
                'label' => 'パスワード',
                'rules' => 'required'
            )
        )
);

なお、この状態で、runに引数を渡さないと何も検証されません。

controllerにどの定義を使うか示すために runに引数として使いたい定義の名前を渡すよう修正します。

application/controllers/MyValidate.php - 修正箇所

        // runに引数を与えました。
        if($this->form_validation->run('enter_name') === false){ 
            $this->load->view('name_form');

これで同じ様に検証が行われ、別のバリデーションも定義できるようになったと思います。
(多分。私は今回 1画面しか試していないので。)

環境:
  Win 10 x64
  Bitnami WAMP Stack 5.5.30-0 (PHP 5.5.30)
  CodeIgniter-3.0.3

  ファイルは C:\Bitnami\wampstack-5.5.30-0\apache2\htdocs\qait9721 に配置。
  (CodeIgniter-3.0.3.zip の readme.rst が htdocs\qait9721\readme.rstに来るように展開)
編集 履歴 (2)
  • ※コメント欄に文字数制限があったので、↓にコメントさせていただきました。ありがとうございました! -

ご回答ありがとうございます!
わざわざ環境を作ってまで試していただいて、感謝いたします。

投稿いただいた内容を見たところ、こちらの認識と同じでした。

// ここではrunに引数を与えていません
    if($this->form_validation->run() === false){ 

ここが肝かと思ったのですが、引数は指定しなくてもいいんですね。。

ひとつこちらの環境と異なったのが、formから受け取ったデータではないので
ここの通りset_dataでデータを設定したくらいです。

もう少し悩んでみます!

※外部定義した部分の配列名がscanになってましたが、正しくはinquiryでした。
投稿にあたって書き換えた部分ですので、実際は統一されています。失礼いたしました。。

編集 履歴 (0)
  • 軽くしか試していないですが、
    http://www.codeigniter.com/user_guide/libraries/form_validation.html#CI_Form_validation::set_data
    にある通り、 set_data は form_validationを返すようです。



    -
  • なので、
    if($this->form_validation->set_data($data)->run('inquiry')===false){
    の様にすればいけそうです。
    -
  • なるほど!確かにドキュメントを見る限り、動きそうですね!
    (開発環境から離れてしまったので、明日早速確認します)

    ありがとうございます。
    重要な情報を載せてなくて失礼いたしました。。
    -
  • 試してみましたが、やはりだめでした...
    $this->form_validation->set_rules で書いたらチェックが走ります。application/config/form_validation.phpを使ってくれないようです。。
    -
  • 'form' helperがロードされておらず、'form_validation'もコンストラクタでロードされてますが、それらをform_validation->runの直前に持ってきたらどうなりますか? -
  • 度々ありがとうございます。残念ながら変わらずでした。
    新しくCI3の環境を作り確認したら外部ファイルをみてくれました。そこでは'form_validation'をloadしたタイミングでform_validation.phpの内容を取得していました(system/libraries/Form_Validation.phpのコンストラクタをみたところ)
    -
  • 解決しました。。application/libraries に My_Form_validation.phpが存在しておりました。ファイルを一時リネームしたら、期待通りに動きました。
    単に4,5個関数が定義されているだけなのですが、それが影響するとは。。勉強不足でした。
    > flied_onion様
    何度もアドバイス頂き、ありがとうございました。
    -
  • 【追記】このままだとMy_Form_validation.phpが使えないのでよく調べたら、ファイル名とクラス名が"MY"ではなく"My"になっていました。。CI2から持ってきたので、移行時の作業漏れでした。失礼いたしました。。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。