CodeIgniter表单验证在模型中回调



嗨,我希望您能为此提供帮助。我在这个问题上看到了许多相同的问题,它们都不适合我。

我正在使用CodeIgniter 2.2.2并尝试在模型中创建形式验证,以便多个控制器可以访问它。表单验证无法在模型中声明的自定义回调上正确返回。

// in Model
function validateErrors() {
   $rules = array(
      array('field'=>'username', 'label'=>'User', 'rules'=>'trim|required|callback_userPrefix'),
      array('field'=>'password', 'label'=>'Password', 'rules'=>'trim|required|callback_passwordNotEmpty'),
   );
   $this->load->library('form_validation');
   $this->form_validation->set_rules($rules);
   if ($this->form_validation->run() == FALSE) {
      $errors = array();
      foreach ($rules as $r)
          $errors[$r['field']] = $this->form_validation->error($r['field']);
      return $errors;
   }
   return false;
}
public function userPrefix() {
   $find = 'user_';
   if (strpos($this->input->post('username'), $find) != 0) {
      $this->form_validation->set_message('userPrefix', 'Username not allowed.');
      return false;
   }
   return true;
}
public function passwordNotEmpty() {
   // not the actual callback just an example
   if (empty($this->input->post('password'))) {
      $this->form_validation->set_message('passwordNotEmpty', 'Password cannot be blank.');
      return false;
   }
   return true;
}

因此可以在控制器中访问:

// in Controller
if ($this->input->post()) {
   $this->load->model('ModelName','model1', true);
   $validation_errors = $this->model1->validateErrors();
   if ($validation_errors === false) {
      // continue saving record
   } else {
      print_r($validation_errors); exit;
   }
}

我想创建每个用户登录的表单验证。但是,由于多个控制器使用相同的验证,因此我在模型中声明了验证及其自定义回调,以最大程度地减少控制器中的编码长度(希望最小化)。

此外,此答案还说您可以在模型中进行表单验证(还显示在模型中声明的回调)。我尝试过,但对我不起作用。

有人可以帮我吗?非常感谢!

单独调用额外方法,例如:

// in Model
function validateErrors() {
   $rules = array(
      array('field'=>'username', 'label'=>'User', 'rules'=>'trim|required'),
      array('field'=>'password', 'label'=>'Password', 'rules'=>'trim|required'),
   );
   $this->load->library('form_validation');
   $this->form_validation->set_rules($rules);
   if ($this->form_validation->run() == FALSE) {
        // something something 
   }
   // 
   elseif( $this->userPrefix() == false)
   {
      // something 
   } 
   elseif( $this->passwordNotEmpty() == false)
   {
      // something 
   } 
   else{ return true;  } 
}

如果您有一系列数据,则回调非常好 - 例如,如果您验证了一组用户名,该字段是用户名[]。但是,我只是遇到了一些问题,关于什么回调可以做到的,我认为上述代码实际上更清晰。fyi -$ this-> input-> post('fieldName') - 在您的模型中始终可用。换句话说,它不取决于成为CodeIgniter表单验证的一部分。

我已经完成了解决方法,这要归功于@cartalot和 @marcofsn的建议。我确实必须修改form_validation类(感谢@marcofsn),并且我真的无法通过set_rules方法在模型中声明自定义回调,因此我必须分别调用每个自定义回调(谢谢@cartalot)。

这是我的代码:

// in Model
function validationErrors() {
   $rules = array(
      array('field'=>'username', 'label'=>'User', 'rules'=>'trim|required'),
      array('field'=>'password', 'label'=>'Password', 'rules'=>'trim|required'),
   );
   $this->load->library('form_validation');
   $this->form_validation->set_rules($rules);
   $errors = array();
   if ($this->form_validation->run() == FALSE)
      foreach ($rules as $r)
         $errors[$r['field']] = $this->form_validation->error($r['field']);
   if (!$errors['username'])
      if ($this->userPrefix( $this->input->post('username'), 'username'))
         $errors['username'] = $this->form_validation->error('username');
   if (!$errors['password'])
      if ($this->passwordNotEmpty( $this->input->post('password'), 'password'))
         $errors['password'] = $this->form_validation->error('password');
   if (!empty($errors)) return $errors;
   else return false;
}
function userPrefix($value, $field) {
   $find = 'user_';
   if (strpos($value, $find) != 0) {
      $this->form_validation->set_field_error($field, sprintf('Username not allowed.'));
   }
   return (strpos($value, $find) != 0);
}
function passwordNotEmpty($value, $field) {
   if (empty($value)) {
      $this->form_validation->set_field_error($field, sprintf('Password cannot be blank.'));
   }
   return (empty($value));
}

我还将功能set_field_error添加到Form_validation类中以设置自定义错误消息:

public function set_field_error($field, $value)
{
    if (isset($this->_field_data[$field]))
        $this->_field_data[$field]['error'] = $value;
    return;
}

这样,我现在可以在控制器中使用模型函数validationErrors,例如:

if ($this->input->post()) {
    $this->load->model('ModelName', 'model1', true);
    $validation_errors = $this->model1->validationErrors();
    if ($validation_errors === false) {
        // continue saving data
    } else {
        print_r($validation_errors);
        exit;
    }
}

再次感谢帮助我提出解决方法的人们。我希望这可以帮助其他人遇到与我相同的问题。

这是基于 @cartalot的想法,最好做到这一点,因为当验证失败时,这将检查所有自定义验证方法:

if ($this->form_validation->run() == FALSE) {
        $standard_error = form_error($field)
        if($model_object->model_method($post_value['some]) == FALSE) 
        {
            //here manually fill error for display on form
        }
        if($model_object->model_method2($post_value['some2]) == FALSE) 
        {
            //here manually fill error for display on form
        }
   }

编辑(对于CI3):更好的是,您可以定义仅返回规则数组的模型方法,然后在验证 -> run()设置之前从您的$ model_object-> model_object-> maded_that_that_returns_rule_arlay()。该规则可以包含可召唤的匿名函数 - 更多信息在此处

最新更新