【问题标题】:Codeigniter form validation callback in model模型中的 Codeigniter 表单验证回调
【发布时间】:2016-10-23 18:39:09
【问题描述】:

您好,希望您能帮我解决这个问题。 我在这个问题上看到了许多相同的问题,但没有一个对我有用。

我正在使用 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 说您可以在模型中进行表单验证(还显示模型中声明的回调应该有效)。我试过了,但对我不起作用。

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

【问题讨论】:

  • 也许这是升级到 Codeigniter 3 的原因?升级有巨大的优势,而且没有太多的重大变化。然后你可以在你的模型中使用 callable ,比如:codeigniter.com/user_guide/libraries/…
  • @cartalot 这是否意味着它无法完成?我无法升级到 v3,因为我只能访问我当前公司系统上的某些模块
  • 与我们分享您的 html,然后更容易弄清楚发生了什么。
  • 你在你的 CI 中使用 HMVC 吗? (我的意思是,模块化 CI)?如果是这样,您必须欺骗一下 Form_validation 类....

标签: php forms codeigniter validation


【解决方案1】:

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

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

}

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

【讨论】:

    【解决方案2】:

    感谢@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;
        }
    }
    

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

    【讨论】:

    • 很高兴你通过了这个。绝对鼓励您的公司升级到第 3 版 - 它相对容易做到,而且除了额外的安全性 - 它的性能要快得多。
    【解决方案3】:

    这是基于@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->method_that_returns_rule_array() 设置此规则。该规则可以包含可调用的匿名函数 - more info here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多