Codeigniterのバリデーションで配列を使用する際の注意点

最近、symfonyを使うまでも無い比較的小さな規模のWebアプリケーション開発には、Codeigniterを使用しています。
 Codeigniterは、PHPをある程度習得していればそれほど時間をかけず開発する事が出来、何より軽量でサクサク動作します。
丁度ブログのネタが無いので、最近Codeigniterのバリデーションでハマッタ所を書きたいと思います。

フォーム・バリデーションで配列を使う場合、特定の条件で検証ルールを使用すると意図しないバリデーションエラーが発生する場合があります。

条件は以下になります。
 1. input type="text" タグのname属性に配列を使う。
 2. 検証ルールに、required(必須)を指定しない
 3. preg_matchを使用する検証ルールを指定する。(numeric, integer, alphaなど)
 4. テキストボックス入力時にブランク(何も入力しない)でバリデーション実行

 例)
  ○ ビュー側(HTML)が以下のようになっている場合
  <input type="text" name="hoge[num1]" value="" />
  <input type="text" name="hoge[num2]" value="" />
  <input type="text" name="hoge[alpha]" value="" />
 
  ○ コントローラ側 検証ルール
  // 必須じゃないよ
  $this->form_validation->set_rules(‘hoge[num1]’, ‘数字1’, ‘integer’)
  $this->form_validation->set_rules(‘hoge[num2]’, ‘数字2’, ‘numeric’)
  $this->form_validation->set_rules(‘hoge[alpha]’, ‘アルファベット’, ‘alpha’)
 

上記条件で、バリデーションを行うとテキストボックスがブランクにも関わらず以下のエラーが発生します。
  "hoge1 欄には、整数以外は入力できません。"
  "hoge2 欄には、数字以外は入力できません。"
  "hoge3 欄には、半角アルファベット以外は入力できません。"

このエラーを防ぐには、CI_Form_validationクラスの、_reduce_array()関数を修正する必要があります。
※ コアクラスを直接修正するのではなく、MY_Form_validationを作成し対象関数のみoverrideした方がいいでしょう。

/**
 * Traverse a multidimensional $_POST array index until the data is found
 *
 * @access    private
 * @param    array
 * @param    array
 * @param    integer
 * @return    mixed
 */       
function _reduce_array($array, $keys, $i = 0)
{
    if (is_array($array))
    {
        if (isset($keys[$i]))
        {
            if (isset($array[$keys[$i]]))
            {
                $array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
            }
            else
            {
                return NULL;
            }
        }
        else
        {
            return $array;
        }
    }
    //  —– 以下の処理を追加 —-
    // ブランクの場合は、NULLを返す。
    if ($array==”)
    {
        unset($array);
        $array = NULL;
    }
   // ———————————–

    return $array;

このバリデーションの仕組みは、1.7.0からみたいなので現時点(1.7.2)のバージョンだとこういったバグも
まだまだありそう。

今後も気づいた点等があったらちょくちょく記事にしていきたいと思います。

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL