【问题标题】:CodeIgniter: validating form array not workingCodeIgniter:验证表单数组不起作用
【发布时间】:2012-05-18 02:48:47
【问题描述】:

我有一组需要验证的个人资料数据:

$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 验证会报错。 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)

【问题讨论】:

  • profile_namebirthdate 也是空的?
  • 是的,我刚刚提交了表单,没有任何输入来显示结构。
  • 我可以看看你的 HTML 标记吗? Pastebin
  • @StackOverflowNewbie - 我下面的解决方案有效吗?
  • @StackOverflowNewbie - 你过得怎么样?

标签: codeigniter codeigniter-2


【解决方案1】:

好的 - 我刚刚花了一个小时来解决这个问题 - 我已经解决了问题+解决方案

问题在于,当您正在测试的变量是数组的一部分时,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]");
         }
    }

【讨论】:

    【解决方案2】:

    让我们试着把它分解成几个部分。希望能帮到你。

    我假设您正在使用第二个“TRUE”参数对 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();
    

    【讨论】:

    • 我获取 POST 变量的原因是因为表单是由我的应用程序动态生成的。我不能只为“height”添加规则,因为它实际上是“height_0”、“height_1”、“height_2”等——而且我事先并不知道这些事情。所以,我抓住 POST,遍历它们并在每次迭代中分配规则。这就是为什么我说我有一个“个人资料数据数组”......
    • 另外,我使用 $this->input->post('user_group_profiles') 的原因是我只想获取 POST 数组的那一部分。
    猜你喜欢
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2020-09-28
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多