【问题标题】:at least one field must be filled, cakephp validation至少必须填写一个字段,cakephp 验证
【发布时间】:2009-09-03 12:02:14
【问题描述】:

我有 4 个可选字段,但至少 1 个字段(任意字段)必须填写?

有什么简单的方法吗?

【问题讨论】:

    标签: cakephp


    【解决方案1】:

    custom validation rule 是要走的路!

    var $validate = array(
        'myField1' => array('atLeastOne'),
        'myField2' => array('atLeastOne'),
        'myField3' => array('atLeastOne'),
        'myField4' => array('atLeastOne')
    );
    
    function atLeastOne($data) {
        return !empty($this->data[$this->name]['myField1'])
               || !empty($this->data[$this->name]['myField2'])
               || !empty($this->data[$this->name]['myField3'])
               || !empty($this->data[$this->name]['myField4']);
    }
    

    您还可以传入要比较的所有字段的额外参数,并从中制作更通用的功能。

    var $validate = array(
        'myField1' => array('atLeastOne', 'myField2', 'myField3', 'myField4'),
        ...
    );
    
    // just pulled out of thin air (i.e. untested)
    function atLeastOne($data) {
        $args = func_get_args();  // will contain $data, 'myField2', 'myField3', ...
    
        foreach ($args as $name) {
            if (is_array($name)) {
                $name = current(array_keys($name));
            }
            if (!empty($this->data[$this->name][$name])) {
                return true;
            }
        }
    
        return false;
    }
    

    【讨论】:

    • 这太可怕了,几天前我几乎逐行写了完全相同的代码????
    • 我想指出,所有规则都需要 allowEmpty = null。否则,规则将被忽略 (allowEmpty = true) 或不执行而失败 (allowEmpty = false)。如果您不考虑这一点,可能会让人感到困惑:)。
    • 此规则与同一字段中的其他规则一起使用时会产生问题。我必须将其作为数组中的第一条规则才能使其正常工作。
    【解决方案2】:

    您可能需要使用beforeValidate() 回调手动实现验证。示例(在您的模型中,我们将其称为 Item):

    function beforeValidate(){
        $valid = false;
        if(!empty($this->data['Item']['foo'])){
            $valid = true;
        }
        // do that same thing for the other three fields, setting $valid to true if any of the fields has a value.
        return $valid && parent::beforeValidate(); 
    }
    

    你也可以像这样做一个长的比较作业,但我发现这种废话真的很难阅读:

    function beforeValidate(){
        $valid = !empty($this->data['Item']['foo']) || !empty($this->data['Item']['bar']) || !empty($this->data['Item']['baz']) || !empty($this->data['Item']['bling'])
        return $valid && parent::beforeValidate(); 
    }
    

    祝你好运!

    【讨论】:

    • +1 我同意在模型中使用 beforeValidate。您还可以设置一个字段名称数组并循环遍历它。如果您要检查的字段超过 3-4 个,这将特别有用。
    • 这种方法的问题在于,它颠覆了正常的验证过程,除非并且直到四个“特殊字段”验证,否则您不会收到同一表单中其他字段的错误消息。跨度>
    • deceze - 是的,但是如果您需要显示特定于字段的错误消息,添加对 invalidate() 的调用将是微不足道的。
    • 不,我是说表单中的 other 字段,at-least-one 规则未涵盖的字段,不会得到验证。您提交表单,它只会在 4 个 at-least-one 字段中为您提供错误,您填写一个,再次提交表单,然后它才会在其他字段中为您提供错误表格。不利于用户体验。该手册还指出,beforeValidate 回调旨在为验证准备数据,而不是验证它。 book.cakephp.org/view/682/beforeValidate
    猜你喜欢
    • 2014-10-16
    • 2014-01-07
    • 2015-03-08
    • 2020-03-31
    • 2013-01-05
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多