Php 在不同模型中使用单个自定义验证规则

Php 在不同模型中使用单个自定义验证规则,php,validation,model,cakephp-2.0,Php,Validation,Model,Cakephp 2.0,我正试图用CakePHP2编写我的第一个项目(我以前使用过CakePHP1),我有以下问题 我有几个模型需要字段(个人数字代码)的自定义验证规则。验证规则非常大,因此我不想在每个模型中重复代码 相反,我考虑用一个函数编写一个组件,该函数将接收一个字符串作为参数并对其进行验证,然后从每个模型中调用特定的函数 我读到控制器中应该使用组件,所以这可能不是最好的方法 我试图做的实际上是扩展ModelValidator并添加我自己的自定义规则,但我不知道这是否可行 谢谢您的帮助。否,组件不适用于型号。我对

我正试图用CakePHP2编写我的第一个项目(我以前使用过CakePHP1),我有以下问题

我有几个模型需要字段(个人数字代码)的自定义验证规则。验证规则非常大,因此我不想在每个模型中重复代码

相反,我考虑用一个函数编写一个组件,该函数将接收一个字符串作为参数并对其进行验证,然后从每个模型中调用特定的函数

我读到控制器中应该使用组件,所以这可能不是最好的方法

我试图做的实际上是扩展ModelValidator并添加我自己的自定义规则,但我不知道这是否可行


谢谢您的帮助。

否,组件不适用于型号。我对自定义验证规则所做的是向AppModel添加方法。然后,您可以在模型的任何验证数组中使用它们

如果您还不知道如何使用自定义验证方法,请参阅“蛋糕书”中关于制作自定义验证方法的部分:

但是,不要将该方法放在需要的每个模型中,而是将其放在您的AppModel中(如果您没有AppModel类,请创建一个如下所示的类,并将其保存到
app/model/AppModel.php
。您的所有模型都将继承该类,因此您的自定义验证方法将可用于任何模型。)

下面是一个简单的例子:

/**
 * app/Model/AppModel.php
 */
class AppModel extends Model {

    /**
     * Validation rule for integers
     *
     * @param  mixed $value
     * @return bool
     */
    public function validateInteger($value) {
        return preg_match('/^\d+$/', array_shift($value));
    }

}

/**
 * app/Model/MyModel.php
 */
class MyModel extends AppModel {

    /**
     * Validation
     *
     * @var array
     */
    public $validate = array(
        'my_field' => array(
            'rule' => 'validateInteger',
            'message' => 'This field only accepts integers'
        )
    );

}

我也曾尝试过定制验证行为,其中包含所有这些验证方法,但由于行为的局限性,我发现它工作得不是特别好,也不那么方便。

我找到了我自己问题的答案:行为

CakePHP结构建议:

  • 应在控制器中使用组件

  • 应在视图中使用辅助对象

  • 行为应该在模型中使用

要定义行为,我执行了以下操作:

  • 在app/Model/Behavior/ValidateBehavior.php文件中:

    class ValidateBehavior extends ModelBehavior {
    
        // the first param is the model object
        public function isValidCnp($Model, $data) {
    
        // data is an array that contains the field name and value
        // define validations rules here
        // return true or false
        }
    }
    
  • 在我的模型app/model/User.php中,我需要验证数据:

     class User extends AppModel {
    
        // link the behavior to the model
        public $actsAs = array('Validate');
    
        // define a custom validation rule that calls a function from the behavior
        public $validate = array(
           'cnp' => array(
               'custom' => array(
                  'rule' => array('isValidCnp')
               )
            ),
        );
     }
    
  • 行为的好处在于,它们的行为类似于父类,还可以包含beforeSave、beforeDelete等的回调函数

    模型可以从行为调用函数,就像他自己的方法一样,这意味着行为也可以在控制器中使用:

    $this->User->isValidCnp()
    

    这是一个很好的答案,但不幸的是,它并不完全适用于我所寻找的。我正在处理的项目非常大,因此通过在其中添加不同的方法,AppModel将变得很难维护,而且这些方法不是每个模型都需要的。我确实知道如何创建自定义验证器方法,并且我在大多数情况下都会使用它们,但是我尝试集成的验证规则更大,我不想重复同样的代码。我认为接口可能有用(模型扩展了AppModel并实现了带有验证规则的接口)。不,接口是个坏主意,因为它们只定义方法名称和参数(那么也许你应该考虑将你的验证方法添加到行为中,当你需要时,你可以在你的模型中包含这些方法。但是我发现这种方法并不理想。是的,我就是这么做的。它可能不理想,但现在我看不到任何其他方法。