模型

时间:2016-06-22 02:30:34

标签: php forms codeigniter validation

嗨,我希望你能帮助我。 我在这个问题上看到了许多相同的问题,但这些问题对我来说都不起作用。

我正在使用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;
}

所以它可以在Controller中访问,如:

// 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;
   }
}

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

此外,this answer表示您可以在模型中执行表单验证(还显示模型中声明的回调可能起作用)。我试过了,但不适合我。

任何人都可以帮助我吗?非常感谢你!

3 个答案:

答案 0 :(得分:2)

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

// 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;  } 

}

如果您有一个数据数组,回调非常好 - 例如,如果您正在验证字段为username []的一组用户名。但我刚刚回答了一些关于回调可以做什么和不能回答的问题,我认为上面的代码实际上更清晰。 此外,fyi - $ this-> input-> post('fieldname') - 在您的模型中始终可用。换句话说,它不依赖于作为codeigniter表单验证的一部分。

答案 1 :(得分:1)

由于@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));
}

我还在Form_validation类中添加了函数set_field_error,以便能够设置自定义错误消息:

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;
    }
}

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

答案 2 :(得分:0)

这是基于@ 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
        }
   }

EDIT(对于CI3):更好的是,您可以定义仅返回规则数组的模型方法,然后在验证之前 - >运行()从$ model_object-> method_that_returns_rule_array()设置此规则。该规则可以包含可调用的匿名函数 - more info here