嗨,我希望您能为此提供帮助。我在这个问题上看到了许多相同的问题,它们都不适合我。
我正在使用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()。该规则可以包含可召唤的匿名函数 - 更多信息在此处