嗨,我希望你能帮助我。 我在这个问题上看到了许多相同的问题,但这些问题对我来说都不起作用。
我正在使用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表示您可以在模型中执行表单验证(还显示模型中声明的回调可能起作用)。我试过了,但不适合我。
任何人都可以帮助我吗?非常感谢你!
答案 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