我有一个要处理一些复杂规则的表格;例如,我必须验证分为三个字段(天,月,年)的两个数据,并且必须检查第一个在第二个之前。
这是我的控制人:
public function booking($data, $lang, $page)
{
$this->load->helper('form');
$this->load->helper('captcha');
$this->load->helper('custom_form');
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('', '<br />');
$data['captcha'] = form_captcha();
$this->session->captcha = $data['captcha']['word'];
$this->form_validation->set_rules('form_place', 'Place', 'required');
$this->form_validation->set_rules('form_nbPeople', 'Number of people', 'required');
$this->form_validation->set_rules('form_dateArrivalDay', '', 'callback_form_checkArrivalDate');
$this->form_validation->set_rules('form_dateDepartureDay', '', 'callback_form_checkDepartureDate');
$this->form_validation->set_rules('form_dateArrivalDay', '', 'callback_form_checkDateConsistency');
$this->form_validation->set_rules('form_name', 'Name', 'required');
$this->form_validation->set_rules('form_phone', '', 'callback_form_checkEmailOrPhone');
$this->form_validation->set_rules('form_captcha', '', 'callback_form_checkCaptcha');
if ($this->form_validation->run() == FALSE)
{
$this->load->view($lang.'/'.$page, $data);
}
else
{
$this->load->view($lang.'/'.$page.'-success', $data);
}
}
这是我的helpers/custom_form_helper.php
文件:
function form_checkArrivalDate()
{
$d = intval($this->input->post('form_dateArrivalDay'));
$m = intval($this->input->post('form_dateArrivalMonth'));
$y = intval($this->input->post('form_dateArrivalYear'));
return(checkdate($m, $d, $y));
}
function form_checkDepartureDate()
{
$d = intval($this->input->post('form_dateDepartureDay'));
$m = intval($this->input->post('form_dateDepartureMonth'));
$y = intval($this->input->post('form_dateDepartureYear'));
return(checkdate($m, $d, $y));
}
function form_checkDateConsistency()
{
$da = intval($this->input->post('form_dateArrivalDay'));
$ma = intval($this->input->post('form_dateArrivalMonth'));
$ya = intval($this->input->post('form_dateArrivalYear'));
$dp = intval($this->input->post('form_dateDepartureDay'));
$mp = intval($this->input->post('form_dateDepartureMonth'));
$yp = intval($this->input->post('form_dateDepartureYear'));
$a = mktime(0, 0, 0, $ma, $da, $ya);
$p = mktime(0, 0, 0, $mp, $dp, $yp);
return($a < $p);
}
无论我在“ form_dateArrivalDay”字段和其他字段中输入什么,验证始终会失败。其他不依赖自定义回调的验证器不存在此问题。
如果我从set_rules
(第一个参数)中取出字段名称,则验证始终会通过。
有什么我想念的吗?
答案 0 :(得分:0)
所以,如果有人想知道答案,我是说我如何解决自己的问题。
该代码存在一些错误。
第一个是因为我的回调函数(如form_checkArrivalDate
不在控制器类中,而是在另一个文件中,更确切地在助手custom_form_helper.php
中)。这些功能必须在控制器类中。这是文档不够精确的一点。
如果希望验证者找到检查功能,则需要将callback_
函数中的名称开头的set_rules
删除。该函数必须是可调用的,并根据检查结果返回TRUE或FALSE。
第二个错误是我的POST字段在我的检查功能中不可见。由于函数不在类之外,因此不会继承属性$this->input->post
。要使CodeIgniter的“超级对象”在函数中可访问,您需要在函数的开头添加$CI =& get_instance();
,并使用$CI
对象而不是$this
。
所以最终我的控制器看起来像这样(我还添加了其他内容,例如语言字符串):
public function booking($data, $lang, $page)
{
$this->load->helper('form');
$this->load->helper('captcha');
$this->load->helper('custom_form');
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('', '<br />');
$data['captcha'] = form_captcha();
$this->session->captcha = $data['captcha']['word'];
$this->form_validation->set_rules('form_place', 'Place', 'required', ['required' => $this->lang->line('form_noPlace')]);
$this->form_validation->set_rules('form_nbPeople', 'Number of people', 'required');
$this->form_validation->set_rules('form_dateArrivalDay', 'Arrival date', 'required|form_checkArrivalDate|form_checkDateConsistency', ['form_checkArrivalDate' => $this->lang->line('form_incorrectDateArrival'), 'form_checkDateConsistency' => $this->lang->line('form_inconsistentDates')]);
$this->form_validation->set_rules('form_dateDepartureDay', 'Departure date', 'required|form_checkDepartureDate', ['form_checkDepartureDate' => $this->lang->line('form_incorrectDateDeparture')]);
$this->form_validation->set_rules('form_name', 'Name', 'required');
$this->form_validation->set_rules('form_phone', 'Phone number', 'form_checkEmailOrPhone', ['form_checkEmailOrPhone' => $this->lang->line('form_incorrectMailOrTel')]);
$this->form_validation->set_rules('form_captcha', 'Captcha', 'form_checkCaptcha', ['form_checkCaptcha' => $this->lang->line('form_incorrectCaptcha')]);
if ($this->form_validation->run() == FALSE)
{
$this->load->view($lang.'/'.$page, $data);
}
else
{
$this->load->view($lang.'/'.$page.'-success', $data);
}
}
这是我的助手:
function form_checkArrivalDate()
{
$CI =& get_instance();
$d = intval($CI->input->post('form_dateArrivalDay'));
$m = intval($CI->input->post('form_dateArrivalMonth'));
$y = intval($CI->input->post('form_dateArrivalYear'));
return(checkdate($m, $d, $y));
}
function form_checkDepartureDate()
{
$CI =& get_instance();
$d = intval($CI->input->post('form_dateDepartureDay'));
$m = intval($CI->input->post('form_dateDepartureMonth'));
$y = intval($CI->input->post('form_dateDepartureYear'));
return(checkdate($m, $d, $y));
}
function form_checkDateConsistency()
{
$CI =& get_instance();
$da = intval($CI->input->post('form_dateArrivalDay'));
$ma = intval($CI->input->post('form_dateArrivalMonth'));
$ya = intval($CI->input->post('form_dateArrivalYear'));
$dp = intval($CI->input->post('form_dateDepartureDay'));
$mp = intval($CI->input->post('form_dateDepartureMonth'));
$yp = intval($CI->input->post('form_dateDepartureYear'));
$a = mktime(0, 0, 0, $ma, $da, $ya);
$p = mktime(0, 0, 0, $mp, $dp, $yp);
return($a < $p);
}
此外,我遇到的一个可能无关但又存在的问题是检查两个字段-form_email
和form_phone
。
我有一个电话号码字段,另一个是电子邮件地址字段;用户必须至少填写两者之一。因此,我在form_phone
上放置了一个仅在两个字段均为空时才返回FALSE的函数。由于两个字段之一可以为空,因此我没有设置“必填”条件。
但这是行不通的,由于某种原因,无论字段中有什么内容,它总是返回TRUE。问题是,猜猜是什么:如果CodeIgniter看到您没有设置“必需”条件,则它不会检查其他条件。是的,这是一种完全愚蠢的行为,我很想知道为什么要实施它-因为根据我所见,这是开发人员的明确选择。
所以我不得不在form_validation.php库中对此进行注释,以使我的验证器正常工作。
if (
($postdata === NULL OR $postdata === '')
&& $callback === FALSE
&& $callable === FALSE
&& ! in_array($rule, array('required', 'isset', 'matches'), TRUE)
)
{
continue;
}