2012-05-18 97 views
5

我有簡檔數據的數組我需要驗證:笨:驗證表單陣列不工作

$user_group_profiles = $this->input->post('user_group_profiles', TRUE); 
foreach ($user_group_profiles as $key => $user_group_profile) 
{ 
    $this->form_validation->set_rules("user_group_profiles[$key][profile_name]", 'Profile Name', 'trim|required'); 
    $this->form_validation->set_rules("user_group_profiles[$key][birthdate]", 'Birthdate', 'trim|required'); 

    // TODO: heigth/weight not required, but the validation somehow makes it required 
    $this->form_validation->set_rules("user_group_profiles[$key][height]", 'Height', 'trim|greater_than[0]'); 
    $this->form_validation->set_rules("user_group_profiles[$key][weight]", 'Weight', 'trim|greater_than[0]'); 
} 

身高和體重是選項,但是,當沒有設置值這些字段,CI驗證抱怨。 A var_dump($user_group_profiles);顯示了這一點:

array 
    'ugp_b33333338' => 
    array 
     'profile_name' => string '' (length=0) 
     'birthdate' => string '' (length=0) 
     'height' => string '' (length=0) 
     'weight' => string '' (length=0) 

任何想法可能是什麼錯?

編輯1:

我走進CI的Form_validation庫並取得$_field_data和公共成員。當我var_export它之後,我得到這個:

'user_group_profiles[ugp_833333338][height]' => 
    array 
     'field' => string 'user_group_profiles[ugp_833333338][height]' (length=42) 
     'label' => string 'Height' (length=6) 
     'rules' => string 'greater_than[1]' (length=15) 
     'is_array' => boolean true 
     'keys' => 
     array 
      0 => string 'user_group_profiles' (length=19) 
      1 => string 'ugp_833333338' (length=13) 
      2 => string 'height' (length=6) 
     'postdata' => string '' (length=0) 
     'error' => string 'The Height field must contain a number greater than 1.' (length=54) 
+1

'profile_name'和'birthdate'也是空的? – Hindol

+0

是的,我剛剛提交了沒有任何輸入的表單來顯示結構。 – StackOverflowNewbie

+0

我可以看看你的HTML標記嗎? [Pastebin](http://pastebin.com/) – Rocco

回答

7

好的 - 我剛剛花了一個小時就這一點 - 我工作出了問題+解決方案

的問題是,當變量你測試是數組的一部分,CI解釋該字段被設置,因此「包含」一個值(即使它是空的)。由於該「值」不是大於0的數字,因此失敗。

因此,當它爲「空」時需要取消設置$ _POST(NOT $ user_group_profiles)變量,以便它通過驗證。注 - 驗證在$ _ POST運行 - 這就是爲什麼你在你重置$ _ POST,而不是$ user_group_profiles

所以解決方法是這樣的:

$user_group_profiles = $this->input->post('user_group_profiles', TRUE); 
foreach ($user_group_profiles as $key => $user_group_profile) 
{ 
    // Set the rules 
    $this->form_validation->set_rules($key."[profile_name]", "Profile Name", "trim|required"); 
    $this->form_validation->set_rules($key."[birthdate]", "Birthdate", "trim|required"); 
    $this->form_validation->set_rules($key."[height]", "Height", "trim|greater_than[0]"); 
    $this->form_validation->set_rules($key."[weight]", "Weight", "trim|greater_than[0]"); 

    // Now check if the field is actually empty 
    if (empty($user_group_profile['height'])) 
    { 
     // If empty, remove from array so CI validation doesnt get tricked and fail 
     unset($_POST[$key]['height']); 
    } 
    if (empty($user_group_profile['weight'])) 
    { 
     unset($_POST[$key]['weight']); 
    } 
} 

我測試過這一點 - 它解決您的問題。

你也可以這樣編程,如果你不想觸及$ _ POST數據:

foreach ($user_group_profiles as $key => $user_group_profile) 
    { 
     // Set the rules 
     $this->form_validation->set_rules($key."[profile_name]", "Profile Name", "trim|required"); 
     $this->form_validation->set_rules($key."[birthdate]", "Birthdate", "trim|required"); 


     // Now check if the field is actually empty 
     if (! empty($user_group_profile['height'])) 
     { 
      $this->form_validation->set_rules($key."[height]", "Height", "trim|greater_than[0]"); 
     } 
     if (! empty($user_group_profile['weight'])) 
     { 
      $this->form_validation->set_rules($key."[weight]", "Weight", "trim|greater_than[0]"); 
     } 
    } 
+0

太棒了!謝謝,它工作! – StackOverflowNewbie

1

讓我們試着把它分解成部分。我希望我能在這裏幫助你。

我假設你正在做的XSS過濾第二個「真」的說法如下:

$user_group_profiles = $this->input->post('user_group_profiles', TRUE); 

實際上,你可以做的表單驗證規則的XSS過濾,或者如果你喜歡過濾規則後的帖子。看到這裏我的偏好:

$this->form_validation->set_rules('profile_name', 'Profile Name', 'xss_clean|trim|required'); 

因此,與知道,現在,我們可以按照他們的表單驗證庫的CI約定。在使用表單驗證庫之前不需要獲取帖子,因爲它可以自動檢測我相信POST數據的字段名稱。例如:

$this->form_validation->set_rules('profile_name', 'Profile Name', 'trim|required|xss_clean'); 
$this->form_validation->set_rules('birthdate', 'Birthdate', 'trim|required|xss_clean'); 
$this->form_validation->set_rules('height', 'Height', 'trim|greater_than[0]|numeric'); 
$this->form_validation->set_rules('weight', 'Weight', 'trim|greater_than[0]|numeric'); 

if ($this->form_validation->run() == FALSE) { 
    $this->load->view('my_view_where_this_post_came_from'); 
} else { 
    $profile_name = $this->input->post('profile_name'); 

    //or if you prefer the XSS check here, this: 
    //$profile_name = $this->input->post('profile_name', TRUE); 

    $birthdate= $this->input->post('birthdate'); 
    $height= $this->input->post('height'); 
    $weight= $this->input->post('weight'); 

    //$user_group_profiles = $this->input->post(); 

} 

我希望這有助於!

編輯:我也只是注意到了這一點。如果你想抓住整個陣列後的代碼是:

$user_group_profiles = $this->input->post(NULL, TRUE); // returns all POST items with XSS filter 
$user_group_profiles = $this->input->post(); // returns all POST items without XSS filter 

不:

$user_group_profiles = $this->input->post('user_group_profiles'); 

一個很好的幫助,如果你不知道你的$ _POST名稱或都搞不清楚,你可以做到這一點,看看數據是否在那裏!像這樣爲你的第一行:

var_dump($_POST); 
exit(); 
+0

我抓住POST變量的原因是因爲表單是由我的應用程序動態生成的。我不能只是將規則添加到「高度」,因爲它實際上是「height_0」,「height_1」,「height_2」等等,而我並不提前知道這些事情。所以,我抓住POST,循環通過它們並在每次迭代中分配規則。這就是爲什麼我說我有一個「配置文件數據陣列」.... – StackOverflowNewbie

+0

此外,我使用'$ this-> input-> post('user_group_profiles')的原因是因爲我只想得到POST數組的一部分。 – StackOverflowNewbie