CI(codeigniter 2.0.2)開發手記(1)-表單元素名稱使用數組形式時存在的bug

表單元素名稱使用數組形式時存在的bug

       CI框架中默認集成了表單驗證的類,表單提交時提供的驗證方式有:必填、長度、郵箱、ip、比較等一些經常使用的驗證,可是默認表單元素比較驗證(matches[form_item])在驗證的表單元素名稱使用數組形式時獲取不到對應表單元素值進行比較。
首先咱們來看一下默認的框架默認的表單驗證類;
路徑:libraries\Form_validation.php
找到matches方法,代碼以下:
function matches($str, $field) {
        if (!isset($_POST[$field])) {
            return FALSE;
        }

        $field = $_POST[$field];

        return ($str !== $field) ? FALSE : TRUE;
    }



       分析一下,當表單元素名(name)以正常的形式(如:password、confirm_password,下面以確認密碼爲例)的狀況下,驗證規則以下
array(
                'field' => 'password',
                'label' => 'Password',
                'rules' => 'trim|required|md5'
            ),
            array(
                'field' => 'confirm_password',
                'label' => 'Confirm Password',
                'rules' => 'trim|matches[password]'
            )


       系統進行驗證confirm_password時matches方法中第二個參數$field爲"password",這個時候$_POST[$field]<=>$_POST["password"],$_POST["password"]獲得表單元素password的值,能夠正確的校驗兩個表單元素;若表單元素名稱使用數組形式(如:model[password]、model[confirm_password])時驗證規則以下
array(
                'field' => 'model[password]',
                'label' => 'Password',
                'rules' => 'trim|required|md5'
            ),
            array(
                'field' => 'model[confirm_password]',
                'label' => 'Confirm Password',
                'rules' => 'trim|matches[model[password]]'
            )


        這個時候進行驗證model[confirm_password]的時候matches方法中第二個參數$field爲"model[password]",這個時候$_POST[$field]<=>$_POST["model[password]"],$_POST["model[password]"]是獲取不到model[confirm_password]值的,那麼不管你輸入兩次密碼相等也返回的是False。


       經過分析發現,咱們能夠對原來的form_validation進行修改,爲了避免破壞框架內核在應用類庫中對原來的類進行擴展覆蓋原有方法,在aplication\libraries下建立MY_Form_validation.php進行擴展(開發規範請參考CI開發手冊,這裏很少說),代碼以下

class MY_Form_validation extends CI_Form_validation {

    //put your code here
    public function __construct($rules = array()) {
        parent::__construct($rules);
    }

    function matches($str, $field) {
        if (strpos($field,'[') !== FALSE) {
            $field_arr = explode('[', str_replace(']', '', $field));
            if (!isset($_POST[$field_arr[0]])) {
                return FALSE;
            }
            $field_val = $this->get_arr_field_val($field_arr, $_POST[$field_arr[0]]);
            return ($str !== $field_val) ? FALSE : TRUE;
        }

        if (!isset($_POST[$field])) {
            return FALSE;
        }

        $field = $_POST[$field];

        return ($str !== $field) ? FALSE : TRUE;
    }

    function get_arr_field_val($arr, $post_val) {
        for ($i = 0; $i < count($arr); $i++) {
            if (isset($arr[$i + 1])) {
                if (isset ($post_val[$arr[$i + 1]])) {
                    $post_val = $post_val[$arr[$i + 1]];
                }
            }
        }
        return $post_val;
    }

}




       覆蓋掉原來的matches添加get_arr_field_val方法。ok搞定,不管是字符串仍是數組的表單元素名均可以正確的驗證。
相關文章
相關標籤/搜索