如何使CodeIgniter可调用工作的空白复选框,自定义表单验证错误

Wou*_*ijn 8 php validation codeigniter codeigniter-3

我的表单验证规则有问题(在单独的配置文件中).复选框会出现这种情况.

为了组织我的验证规则,我创建了一个名为的库文件validation_rules.这个库包含我的所有自定义回调等valid_date.为了能够调用这些规则,我加载库,然后使用以下配置:

array(
    'field' => 'terms',
    'label' => 'lang:reg_lbl_terms',
    'rules' => array(array('terms_accepted', array($ci->validation_rules, 'terms_accepted')))
    ),
Run Code Online (Sandbox Code Playgroud)

$ciCodeIgniter($this)的引用在哪里.

现在这适用于大多数类型的输入,但它不适用于留空的复选框,可能因为它们没有发布.

但是,当我放弃我的库并简单地将回调添加到控制器时,一切都可以正常使用以下配置:

array(
    'field' => 'terms',
    'label' => 'lang:reg_lbl_terms',
    'rules' => array('callback_terms_accepted')
    ),
Run Code Online (Sandbox Code Playgroud)

此外,当我requiredrules数组(或字符串)中的任何位置添加规则时,required规则会被调用(由于未选中复选框,因此返回false),但完全忽略所有其他规则.

这一定是CodeIgniter中的错误吗?有人有解决方案或解决方法吗?当然是一个选择,但我真的不喜欢它.

相关文档:http://www.codeigniter.com/user_guide/libraries/form_validation.html

编辑: Checkbox PHP/HTML:

<?php
$data = array(
    'name'    => 'terms',
    'value'   => 'true'
);
echo form_checkbox($data);
// Results in: <input type="checkbox" name="terms" value="true">
// No set_value() is used.
?>
Run Code Online (Sandbox Code Playgroud)

Wou*_*ijn 0

好吧,我设法解决了我的问题。这里的问题是因为我怀疑 CodeIgniter 中存在与可调用对象相关的错误。

注意:此错误似乎已在 CI 3.0.1+ 中修复。我运行的是 3.0.0 版本。

问题

问题在于 Form_validation 库的_execute函数中有一段代码,用于检查是否required为未发布的字段设置了规则或回调规则。$_POST这适用于复选框,因为当留空时它们不是数组的一部分。这是导致问题的代码:

$callback = FALSE;
if ( ! in_array('required', $rules) && ($postdata === NULL OR $postdata === ''))
{
    // Before we bail out, does the rule contain a callback?
    foreach ($rules as &$rule)
    {
        if (is_string($rule))
        {
            if (strncmp($rule, 'callback_', 9) === 0)
            {
                $callback = TRUE;
                $rules = array(1 => $rule);
                break;
            }
        }
        elseif (is_callable($rule))
        {
            $callback = TRUE;
            $rules = array(1 => $rule);
            break;
        }
    }

    if ( ! $callback)
    {
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果不需要字段或有回调,则此代码用于完全跳过字段的验证。然而,CI 开发人员犯了一个错误,即使用is_callable. 这对于结构如下的普通可调用对象来说当然没问题:

array($this->some_model_or_library, 'function_name')
Run Code Online (Sandbox Code Playgroud)

但是,CodeIgniter 允许您命名回调以便为其设置验证错误,如下所示:

array('my_callback_function', array($this->some_model_or_library, 'function_name'))
Run Code Online (Sandbox Code Playgroud)

毫不奇怪,is_callable当应用于此数组时返回 false,因此跳过验证。

相关文档:http://www.codeigniter.com/user_guide/libraries/form_validation.html#callable-use-anything-as-a-rule

解决方案

就我个人而言,我没有看到上述代码的用途,因为我不想在未发布字段时跳过验证。MY_Form_validation所以我通过创建一个类并覆盖该函数来解决这个问题_execute,只需将代码替换为:

$callback = TRUE;
Run Code Online (Sandbox Code Playgroud)

当然,稍微保守的解决方案是检查多维数组并应用于is_callable适当的元素,如下所示:

if (is_callable($rule)                            // Original check.
|| (is_array($callback) && is_array($callback[1]) // Check if the callback is an array and contains an array as second element.
&& is_callable($callback[1]))                     // Check if the second element is a callable.
Run Code Online (Sandbox Code Playgroud)