CodeIgniter:表单验证回调始终返回False

时间:2019-03-31 17:37:43

标签: php codeigniter validation

我有一个要处理一些复杂规则的表格;例如,我必须验证分为三个字段(天,月,年)的两个数据,并且必须检查第一个在第二个之前。

这是我的控制人:

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(第一个参数)中取出字段名称,则验证始终会通过。

有什么我想念的吗?

1 个答案:

答案 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_emailform_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;
}