CakePHP 2.x CookBook 中文版 第七章 模型 之 数据校验(二)

 

内核核验规则

class  Validation

CakePHP 的 Validation 类包含许多能使模型数据校验更容易的校验规则。这个类包含许多常用的不需要自己编写的校验技术。 下面是全部规则的完整列表及其用法示例。

static  Validation:: alphaNumeric ( mixed $check )

列数据必须只包含字母和数字。

public $validate = array(
    'login' => array(
        'rule'    => 'alphaNumeric',
        'message' => 'Usernames must only contain letters and numbers.'
    )
);
static  Validation:: between ( string $checkinteger $mininteger $max )

列的数据长度必须位于指定的数值范围。必须同时提供最小值和最大值。Uses = not.:

public $validate = array(
    'password' => array(
        'rule'    => array('between', 5, 15),
        'message' => 'Passwords must be between 5 and 15 characters long.'
    )
);

数据的长度是指”字符串数据的字节数”。要小心,当处理非 ASCII 字符时,其值可能大于字符数。

static  Validation:: blank ( mixed $check )

这条规则用于确保列值为空或者其值仅包含空白字符。空白字符包括 空格、tab、回车和换行。

public $validate = array(
    'id' => array(
        'rule' => 'blank',
        'on'   => 'create'
    )
);
static  Validation:: boolean ( string $check )

列数据必须是逻辑值。有效值包括 true 或 false,整数值 0 或 1,字符串值 ‘0’ 或 ‘1’。

public $validate = array(
    'myCheckbox' => array(
        'rule'    => array('boolean'),
        'message' => 'Incorrect value for myCheckbox'
    )
);
static  Validation:: cc ( mixed $checkmixed $type = 'fast'boolean $deep = falsestring $regex = null )

这条规则用于检查数据是否是有效的信用卡编号。它有三个参数:‘type’、 ‘deep’ 和 ‘regex’。

‘type’键能赋的值有‘fast’、 ‘all’下列值之一:

  • amex
  • bankcard
  • diners
  • disc
  • electron
  • enroute
  • jcb
  • maestro
  • mc
  • solo
  • switch
  • visa
  • voyager

如果‘type’设为‘fast’,检验的是主信用卡的编码格式。‘type’设置为‘all’校验所有信用卡类型。也可以将 ‘type’设置为希望检验的类型的数组。

‘deep’键需要设置为逻辑值。如果为 true,校验规则将检查信用卡的 Luhn 算法(http://en.wikipedia.org/wiki/Luhn_algorithm)。默认值为 false。

‘regex’键允许提供自定义的用于校验信用卡编号的正则表达式:

public $validate = array(
    'ccnumber' => array(
        'rule'    => array('cc', array('visa', 'maestro'), false, null),
        'message' => 'The credit card number you supplied was invalid.'
    )
);
static  Validation:: comparison ( mixed $check1string $operator = nullinteger $check2 = null )

Comparison 用于比较数字值。支持 “is greater”、”isless”、”greater or equal”、”less or equal”、”equal to” 和 “not equal”。以下为示例:

public $validate = array(
    'age' => array(
        'rule'    => array('comparison', '>=', 18),
        'message' => 'Must be at least 18 years old to qualify.'
    )
);

public $validate = array(
    'age' => array(
        'rule'    => array('comparison', 'greater or equal', 18),
        'message' => 'Must be at least 18 years old to qualify.'
    )
);
static  Validation:: custom ( mixed $checkstring $regex = null )

用于自定义正则表达式:

public $validate = array(
    'infinite' => array(
        'rule'    => array('custom', '\u221E'),
        'message' => 'Please enter an infinite number.'
    )
);
static  Validation:: date ( string $checkmixed $format = 'ymd'string $regex = null )

这条规则确保提交的数据是正确的日期格式。可以传递一个指定要校验的日期的格式的参数(可以是数组)。此参数可以为下列之一:

  • ‘dmy’ 例如 27-12-2006 或 27-12-06 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘mdy’ 例如 12-27-2006 or 12-27-06 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘ymd’ 例如 2006-12-27 or 06-12-27 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘dMy’ 分别 27 December 2006 or 27 Dec 2006
  • ‘Mdy’ 例如 December 27, 2006 or Dec 27, 2006 (逗号是可选的)
  • ‘My’ 例如 (December 2006 or Dec 2006)
  • ‘my’ 例如 12/2006 or 12/06 (间隔符可以是空格、句点、破折号、斜杠)

如果没有提供这个键,就默认使用 ‘ymd’:

public $validate = array(
    'born' => array(
        'rule'       => array('date', 'ymd'),
        'message'    => 'Enter a valid date in YY-MM-DD format.',
        'allowEmpty' => true
    )
);

当许多数据需要用一个特定的格式存储时,你可能会考虑接受较宽泛的格式并转换,而不是强制用户提供一个指定的格式。你可以为客户做的更多、更好!

static  Validation:: datetime ( array $checkmixed $dateFormat = 'ymd'string $regex = null )

这条规则确保数据是有效的日期时间格式。可以传递一个指定要校验的日期的格式的参数(可以是数组)。此参数可以为下列之一:

  • ‘dmy’ 例如 27-12-2006 或 27-12-06 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘mdy’ 例如 12-27-2006 or 12-27-06 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘ymd’ 例如 2006-12-27 or 06-12-27 (间隔符可以是空格、句点、破折号、斜杠)
  • ‘dMy’ 分别 27 December 2006 or 27 Dec 2006
  • ‘Mdy’ 例如 December 27, 2006 or Dec 27, 2006 (逗号是可选的)
  • ‘My’ 例如 (December 2006 or Dec 2006)
  • ‘my’ 例如 12/2006 or 12/06 (间隔符可以是空格、句点、破折号、斜杠)

如果没有提供这个键,就默认使用 ‘ymd’:

public $validate = array(
    'birthday' => array(
        'rule'    => array('datetime', 'dmy'),
        'message' => 'Please enter a valid date and time.'
    )
);

可以通过传递第二个参数来指定自定义正则表达式。如果使用此参数,就以此为标准进行验证。

与 date() 不同,datetime() 校验日期和时间。

static  Validation:: decimal ( integer $checkinteger $places = nullstring $regex = null )

这条规则确保数据是有效的数字。可以传递一个指定小数点后的数字位数的参数。如果没有传递参数,数据必须是严格意义上的浮点数,如果没有在小数点后发现数字,校验就会失败:

public $validate = array(
    'price' => array(
        'rule' => array('decimal', 2)
    )
);
static  Validation:: email ( string $checkboolean $deep = falsestring $regex = null )

这条规则校验数据是否为有效的邮件地址。传递一个逻辑值作为其第二个参数,这条规则将试图检查地址中的主机是否是有效的:

public $validate = array('email' => array('rule' => 'email'));

public $validate = array(
    'email' => array(
        'rule'    => array('email', true),
        'message' => 'Please supply a valid email address.'
    )
);
static  Validation:: equalTo ( mixed $checkmixed $compareTo )

这条规则确保数据与给定的值类型相同、数值相等。

public $validate = array(
    'food' => array(
        'rule'    => array('equalTo', 'cake'),
        'message' => 'This value must be the string cake'
    )
);
static  Validation:: extension ( mixed $checkarray $extensions = array('gif''jpeg''png''jpg') )

这条规则校验文件扩展名是不是 .jpg 或者 .png。允许以数组方式传递多个扩展名。

public $validate = array(
    'image' => array(
        'rule'    => array('extension', array('gif', 'jpeg', 'png', 'jpg')),
        'message' => 'Please supply a valid image.'
    )
);
static  Validation:: fileSize ( $check$operator = null$size = null )

这条规则允许检测文件长度。可以使用 $operator 来决定所需的比较类型。所有 comparison() 支持的操作这里也支持。 此方法将通过读取 tmp_name 键(如果 $check 是一个包含该键的数组)自动处理来自 $_FILES 的数组值:

public $validate = array(
    'image' => array(
        'rule' => array('filesize', '<=', '1MB'),
        'message' => 'Image must be less than 1MB'
    )
);

2.3 新版功能: 此方法是 2.3 版增加的。

static  Validation:: inList ( string $checkarray $list )

这条规则确保值在给定的集合中。它需要一个值数组。如果列值与给定的数组中的某个值匹配,则列被视为有效。

例如:

public $validate = array(
    'function' => array(
         'allowedChoice' => array(
             'rule'    => array('inList', array('Foo', 'Bar')),
             'message' => 'Enter either Foo or Bar.'
         )
     )
 );
static  Validation:: ip ( string $checkstring $type = 'both' )

这条规则确保被提交的是有效的 IPv4 或 IPv6 地址。接受参数 ‘both’ (默认值)、’IPv4’ 或者 ‘IPv6’。

public $validate = array(
    'clientip' => array(
        'rule'    => array('ip', 'IPv4'), // or 'IPv6' or 'both' (default)
        'message' => 'Please supply a valid IP address.'
    )
);
static  Validation:: isUnique

列数据必须唯一,不能是被其它行用过的。

public $validate = array(
    'login' => array(
        'rule'    => 'isUnique',
        'message' => 'This username has already been taken.'
    )
);
static  Validation:: luhn ( string|array $checkboolean $deep = false )

Luhn 算法:各种标识码的校验算法。更多信息参见 http://en.wikipedia.org/wiki/Luhn_algorithm 。

static  Validation:: maxLength ( string $checkinteger $max )

这条规则确保数据在最大长度范围内。

public $validate = array(
    'login' => array(
        'rule'    => array('maxLength', 15),
        'message' => 'Usernames must be no larger than 15 characters long.'
    )
);

此处的长度是 “字符串数据的字节数”。要小心,当处理非 ASCII 字符时,其值可能大于字符数。

static  Validation:: mimeType ( mixed $checkarray $mimeTypes )

2.2 新版功能.

这条规则校验有效的 mimeType

public $validate = array(
    'image' => array(
        'rule'    => array('mimeType', array('image/gif')),
        'message' => 'Invalid mime type.'
    ),
);
static  Validation:: minLength ( string $checkinteger $min )

这条规则确保数据不低于最短长度。

public $validate = array(
    'login' => array(
        'rule'    => array('minLength', 8),
        'message' => 'Usernames must be at least 8 characters long.'
    )
);

此处的长度是 “字符串数据的字节数”。要小心,当处理非 ASCII 字符时,其值可能大于字符数。

static  Validation:: money ( string $checkstring $symbolPosition = 'left' )

这条规则确保值是一个有效的货币额。

第二个参数定义了货币符号的位置(左/右)。

public $validate = array(
    'salary' => array(
        'rule'    => array('money', 'left'),
        'message' => 'Please supply a valid monetary amount.'
    )
);
static  Validation:: multiple ( mixed $checkmixed $options = array() )

这条规则用于校验 多 select input 表单。所支持的参数有 “in”、”max” 和 “min”。

public $validate = array(
    'multiple' => array(
        'rule' => array('multiple', array(
            'in'  => array('do', 'ray', 'me', 'fa', 'so', 'la', 'ti'),
            'min' => 1,
            'max' => 3
        )),
        'message' => 'Please select one, two or three options'
    )
);
static  Validation:: notEmpty ( mixed $check )

这条规则确保列不是空的。

public $validate = array(
    'title' => array(
        'rule'    => 'notEmpty',
        'message' => 'This field cannot be left blank'
    )
);

不要在校验 多选择的 select input 时使用这条规则,因为这会引起错误。请使用 “multiple” 代替。

static  Validation:: numeric ( string $check )

校验传递的数据是不是有效的数字。

public $validate = array(
    'cars' => array(
        'rule'    => 'numeric',
        'message' => 'Please supply the number of cars.'
    )
);
static  Validation:: naturalNumber ( mixed $checkboolean $allowZero = false )

2.2 新版功能.

这条规则检查传递的数据是不是有效的自然数。如果 $allowZero 被设置为 true,0 也将是可以接受的值。

public $validate = array(
    'wheels' => array(
        'rule'    => 'naturalNumber',
        'message' => 'Please supply the number of wheels.'
    ),
    'airbags' => array(
        'rule'    => array('naturalNumber', true),
        'message' => 'Please supply the number of airbags.'
    ),
);
static  Validation:: phone ( mixed $checkstring $regex = nullstring $country = 'all' )

电话校验针对的是美国电话号码。如果想要校验非美国电话号码,可以提供一个正则表达式作为第二个参数,以覆盖额外的号码格式。

public $validate = array(
    'phone' => array(
        'rule' => array('phone', null, 'us')
    )
);
static  Validation:: postal ( mixed $checkstring $regex = nullstring $country = 'us' )

邮政编码针对的是美国、加拿大、英国、意大利、德国和比利时。对于其它的邮政编码,可以提供一个正则作为第二个参数。

public $validate = array(
    'zipcode' => array(
        'rule' => array('postal', null, 'us')
    )
);
static  Validation:: range ( string $checkinteger $lower = nullinteger $upper = null )

这条规则确保传递的值在给定的范围内。如果没有提供范围,这条规则检测并确认传递的是当前平台上的合法值。

public $validate = array(
    'number' => array(
        'rule'    => array('range', -1, 11),
        'message' => 'Please enter a number between 0 and 10'
    )
);

上例将接受大于 0 (例如 0.01)并且小于 10 (例如 9.99)的值。

注解

范围的 上/下 限是不包含在内的。

static  Validation:: ssn ( mixed $checkstring $regex = nullstring $country = null )

Ssn 校验美国、丹麦和荷兰的社会安全号码。对于其它的社会安全号码,需要提供一个正则表达式。

public $validate = array(
    'ssn' => array(
        'rule' => array('ssn', null, 'us')
    )
);
static  Validation:: time ( string $check )

时间校验判断传递的字符串是不是有效的时间。格式有两种 24 小时制(HH:MM)或者 上/下午制([H]H:MM[a|p]m)。不允许有秒,也不校验秒。

static  Validation:: uploadError ( mixed $check )

2.2 新版功能.

这条规则检测文件上传是否发生了错误。

public $validate = array(
    'image' => array(
        'rule'    => 'uploadError',
        'message' => 'Something went wrong with the upload.'
    ),
);
static  Validation:: url ( string $checkboolean $strict = false )

这条规则检测 URL 格式是否有效。支持 http(s)、ftp(s)、file、news 和 gopher 协议:

public $validate = array(
    'website' => array(
        'rule' => 'url'
    )
);

要确保协议是 url,可以启用严格模式,示例如下:

public $validate = array(
    'website' => array(
        'rule' => array('url', true)
    )
);
static  Validation:: userDefined ( mixed $checkobject $objectstring $methodarray $args = null )

运行一个用户定义的校验。

static  Validation:: uuid ( string $check )

检测值是否是有效的 uuid: http://tools.ietf.org/html/rfc4122

本地化校验

phone() 和 postal() 校验规则将所有它们不知道如何处理的国家前缀传递给带有正确名称的其它类。 例如,如果你住在荷兰,可以创建如下类:

class NlValidation {
    public static function phone($check) {
        // ...
    }
    public static function postal($check) {
        // ...
    }
}

这个文件可以放在 APP/Validation/ 或 App/PluginName/Validation/,但是在尝试使用它之前必须先用 App::uses() 导入。 可以用如下方式在校验类中使用 NLValidation 类:

public $validate = array(
    'phone_no' => array('rule' => array('phone', null, 'nl')),
    'postal_code' => array('rule' => array('postal', null, 'nl')),
);

当模型数据被校验,Validation 会看到它不能处理的 nl 国家编码,并尝试委托给 NlValidation::postal(),将其返回值用作校验 通过/失败 的结果。 这个办法允许你建立一个类来处理本地化子集或者本地化组。 独立检验方法的用法没有改变,其能力通过添加的其它校验器传递。

小技巧

本地化插件已经包含了一些有用的规则: https://github.com/cakephp/localized 你也可以随意贡献你的本地化检验规则。

在控制器中校验数据

虽然正常情况下,你只使用模型的 save 方法,偶尔你也希望只校验数据而不保存它。 例如,你可能希望在把数据真实地保存到数据库前,向用户显示一些附加信息。 此时的数据校验与保存数据时的校验稍有不同。

首先,将数据赋给模型:

$this->ModelName->set($this->request->data);

然后,使用模型的校验方法检测数据是否有效,如果有效返回 true,否则返回 false:

if ($this->ModelName->validates()) {
    // 数据有效的逻辑
} else {
    // 数据无效的逻辑
    $errors = $this->ModelName->validationErrors;
}

只使用模型中指定的校验集的子集校验模型是可取的。 例如,有一个带有 first_name、last_name、email 和 password 的 User 模型。 想要在建立或编辑用户时校验全部四个列规则。 而在用户登录时只校验 email 和 passowrd 规则。 可以通过传递选项数据指定要校验的列来实现:

if ($this->User->validates(array('fieldList' => array('email', 'password')))) {
    // 有效
} else {
    // 无效
}

校验方法调用 invalidFields 方法填充模型的 validationErrors 属性。 invalidFields 方法同时返回这些数据:

$errors = $this->ModelName->invalidFields(); // 包含 validationErrors 数组

校验错误列表在连续调用 invalidFields() 的过程中不会进行清理。 所以如果校验在循环内进行,又想分隔错误集,就不要使用 invalidFields()。取而代之的是使用 validates() 方法并访问模型的 validationErrors 属性。

需要重点注意的是在数据校验前必须将其赋给模型。 这和在保存方法中不同,保存方法允许数据作为参数传递。 另外,谨记不必在调用 save 之前调用校验,因为 save 将在地、实际保存前自动校验数据。

要校验多个模型,使用下列方法:

if ($this->ModelName->saveAll($this->request->data, array('validate' => 'only'))) {
  // 无效
} else {
  // 有效
}

如果在保存前已经校验了数据,可以关闭校验以防止重复检测:

if ($this->ModelName->saveAll($this->request->data, array('validate' => false))) {
    // 保存时不再校验
}

你可能感兴趣的:(cakephp,Cookbook)