#はじめに#
CakePHP(3.8)のバリデーションメソッドまとめです。
バリデーションの基本は、Validationクラスのインスタンスに、チェーンメソッドで適応したルールを記述していきます。
use Cake\Validation\Validator;
$validator = new Validator();
$validator
->requirePresence('age')
->notEmpty('age', 'このフィールドに入力してください')
->nonNegativeInteger('age', '年齢は数字で入力してください。')
Validatorクラスは、基本的にはValidationクラスのラッパーになっています。(例外もあります)
そのため、実際にどのような処理が行われるかを知るためには、Validationクラスを覗く必要があります。
public function nonNegativeInteger($field, $message = null, $when = null)
{
$extra = array_filter(['on' => $when, 'message' => $message]);
return $this->add($field, 'nonNegativeInteger', $extra + [
'rule' => ['naturalNumber', true]
]);
}
##一覧##
メソッド名 | 説明 |
---|---|
add | ルールを追加する |
addNested | ネストされたデータをバリデートする |
addNestedMany | 1対多の関係をバリデートする |
remove | ルールを削除する |
requirePresence | フィールドに存在することを要求する。nullは許容する |
allowEmpty | 空を許容する。3.7から非推奨 |
notEmpty | 空を認めない。フィールドに存在することは要求しない。3.7から非推奨 |
notBlank | 空を認めず、更に半角スペースも認めない |
allowEmptyString | 空を許容し、かつ文字列か |
notEmptyString | 空を認めず、かつ文字列か |
allowEmptyArray | 空を許容し、かつ配列か |
notEmptyArray | 空を認めず、かつ配列 |
allowEmptyFile | 空を許容し、かつファイルか |
notEmptyFile | 空を認めず、かつファイルか |
allowEmptyDate | 空を許容し、かつ日付型か |
notEmptyDate | 空を認めず、かつ日付型か |
allowEmptyTime | 空を許容し、かつ時刻か |
notEmptyTime | 空を認めず、かつ時刻か |
allowEmptyDateTime | 空を許容し、かつdatetime型か |
notEmptyDateTime | 空を認めず、かつdatetime型か |
alphaNumeric | 半角英数字か |
lengthBetween | 指定した文字数の範囲か |
creditCard | クレジットカードの形式か |
greaterThan | 指定した数字を超えるか |
greaterThanOrEqual | 指定した数字以上 |
lessThan | 指定した数字未満 |
lessThanOrEqual | 指定した数字以下 |
equals | 指定した数字と一致 |
notEquals | 指定した数字と不一致 |
sameAs | 指定したフィールドと一致(厳格な比較) |
notSameAs | 指定したフィールドと不一致(厳格な比較) |
equalToField | 指定したフィールドと一致 |
notEqualToField | 指定したフィールドと一致 |
greaterThanToField | 指定したフォールドを超える |
greaterThanOrEqualToField | 指定したフィールド以上 |
lessThanToField | 指定したフィールド未満 |
lessThanOrEqualToField | 指定したフィールド以下 |
containsNonAlphaNumeric | 指定した回数英数字以外が含まれているか |
date | ymd形式がどうか |
datetime | datetime形式がどうか |
time | 時刻の形式かどうか |
boolean | 真偽値かどうか |
decimal | 十進数小数か |
メールアドレス形式か | |
ip | IPアドレスの形式か |
ip4 | IPv4の形式か |
ip6 | IPv6の形式か |
minLength | スカラ値が指定した文字数以下か |
maxLength | スカラ値が指定した文字数以下か |
minLengthBytes | スカラ値が指定したバイト数以下か |
maxLengthBytes | スカラ値が指定したバイト数以下か |
numeric | is_numericか |
naturalNumber | 自然数かどうか |
nonNegativeInteger | 0以上の自然数か |
range | 指定した範囲の数値か |
url | urlの形式か |
urlWithProtocol | urlの形式で、スキーマが必須 |
inList | リストの中に存在するか |
uuid | uuidか |
uploadedFile | ファイルの形式か |
latLong | 経度または緯度の形式か |
latitude | 経度か |
longitude | 緯度か |
ascii | ASCII文字か |
utf8 | BMP UTF-8文字か |
utf8Extended | UTF-8文字か |
integer | 数字か |
isArray | 配列か |
isScaler | スカラ値か |
hexColor | 16進数カラーコードか |
multipleOptions | 複数選択セレクトボックスの値か |
hasAtLeast | フィールドが指定された数以上の要素をもつか |
hasAtMost | フィールドが指定された数以下の要素をもつか |
regex | フィールドが正規表現に一致するか |
#共通してる引数#
##$field
##
バリデーションの対象となる配列の、バリデーションをかけたいフィールドをキーを渡します。
これは、配列で渡すことによって、複数のフィールドを同時にバリデーションを適応することが可能です。
##$message = null
##
バリデーションが発動した際の、エラーメッセージを指定します。この引数が渡されなかった場合、デフォルトのエラーメッセージが出力されます。
##$when = null
##
以下の3つから選択することができます。
- create 新規作成時にバリデーションを適応する
- update 更新時にバリデーションを適応する
- コールバック関数
3つ目のコールバック関数について、具体例を提示します。
$validator->requirePresence('credit_card', function ($context) {
if(isset($context['data']['payment']) {
$context['data']['payment'] === 'credit';
}
return false;
});
コールバック関数の戻り値は、真偽値か、エラーメッセージを意味する文字列である必要があります。
$context['data']
には、同時に送られた配列が入っています。
これは、支払い方法がクレジットカードの場合には、クレジットカード番号が必須項目となる例です。
#ルールに関するメソッド#
これらは、他のメソッドと異なり、ルールを追加するために使用されるメソッドです。
##add#
$validtor->add($field, $name, $rule = [])
新しいルールを追加することができます。
以下のように既存のルールを追加することができますが、基本的にはラッパーから読んだほうが簡潔になります。
// これらは同じルールが適応される。addを使用して追加した場合には、ルールの名前を決めることができる。
$validator->add('password', [
'size' => [
'rule' => ['lengthBetween', 8, 20],
'message' => 'パスワードは8文字以上20文字以下にする必要があります。'
]
]);
$validator->lengthBetween('password', [8, 20], 'パスワードは8文字以上20文字以下にする必要があります。');
addが真価を発揮するのは、自分で作ったルールを適応させられるところです。
##addNested##
$validator->addNested($field, Validator $validator, $message = null, $when = null)
バリデーションインスタンスを与えて、バリデーションをネストすることができます。
とはいえ、エンティティをバリデーションする際には、アソシエーションするモデル側でバリデーションルールを記述すれば、通常ネストされている
バリデーションも適応されるので、これはモデルのないフォームに利用されます。
##addNestedMany##
$validator->addNestedMany($field, Validator $validator, $message = null, $when = null)
1:多の関係をネストします。addNestedと同じく、モデルのないフォームに利用されます。
##remove##
$validator->remove($field, $rule = null)
フィールドのルールを削除します。$rule
には、ルール名を指定します。
$rule
が指定されなかったときは、そのフィールドのすべてのルールが削除されます。
#通常のバリデーションメソッド#
##requirePresence##
$Validator->requirePresence($field, $mode = true, $message = null)
バリデーションの対象となる配列のフィールドに対して、実在することを求めます。
具体的には、array_key_exists
を用いてキーの存在を確かめるため、nullは許容されます。
そのため、notNull制約を実現したい場合には、notEmpty
などと組み合わせて使うことが一般的です。
また、$mode
を指定することによって、以下の5つのモードを選択することができます。デフォルトはtrueです。
- true 常にこのフィールドが存在することが求められる。
- false フィールドが存在する必要がなくなる。
- create 新規作成時にバリデーションを適応する
- update 更新時にバリデーションを適応する
- コールバック関数
一般的なバリデーションメソッドと引数の順番が違うのは、requirePrecenceはラッパーメソッドではないからです。
##allowEmpty##
$validator->allowEmpty($filed, $when = null, $message = null)
空を許可します。これも、ラッパーメソッドではないので、引数の順序が異なります。
3.7からは、非推奨となり、代わりに以下のメソッドを使うことが推奨されています。
notEmptyString()
notEmptyArray()
notEmptyFile()
notEmptyDate()
notEmptyDatetime()
notEmptyTime()
##notEmpty##
$validator->notEmpty($field, $message = null, $when = null)
空を認めません。具体的には '' や、 null 、 [] といった値(空の配列)です。これもラッパーメソッドではありません。
allowEmpty
と同じく、3.7から非推奨となり、以下のメソッドの使用が推奨されています。
notEmptyString()
notEmptyArray()
notEmptyFile()
notEmptyDate()
notEmptyDatetime()
notEmptyTime()
##notBlank##
$validator->notBlank($field, $message = null, $when = null)
空を認めないところはnotEmpty
と同じですが、相違点は空白文字も認めないところです。
全角スペースは通してしまうので、注意が必要です。
##alphaNumeric##
$validator->alphaNumeric($field, $message = null, $when = null)
英数字だけであることをチェックします。
内部的にはなんだか見慣れない正規表現が使われています。
public static function alphaNumeric($check)
{
if (empty($check) && $check !== '0') {
return false;
}
return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/Du');
}
これは、Unicodeカテゴリでチェックされていることがわかります。
そのため日本語は弾いてくれません
/^[a-zA-Z0-9]+$/
のような正規表現を使いましょう。
##lengthBetween##
$validator->lengthBetween($field, array $range, $message = null, $when = null)
数字の範囲を配列で渡して指定します。
##creditCard##
$validator->creditCard($field, $type = 'all', $message = null, $when = null)
クレジットカードの形式かどうかをチェックします。$type
はallとfastから指定できます。
allは各クレジットカード会社の形式に沿っているかどうかチェックし、fastはすべての形式を一度だけチェックします。つまり、
$cards = [
'all' => [
'amex' => '/^3[47]\\d{13}$/',
'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/',
'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/',
'disc' => '/^(?:6011|650\\d)\\d{12}$/',
'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
'enroute' => '/^2(?:014|149)\\d{11}$/',
'jcb' => '/^(3\\d{4}|2131|1800)\\d{11}$/',
'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
'mc' => '/^(5[1-5]\\d{14})|(2(?:22[1-9]|2[3-9][0-9]|[3-6][0-9]{2}|7[0-1][0-9]|720)\\d{12})$/',
'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
'visa' => '/^4\\d{12}(\\d{3})?$/',
'voyager' => '/^8699[0-9]{11}$/'
],
'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/'
];
こういうことですね。
##greaterThan##
$validator->greaterThan($field, $value, $message = null, $when = null)
$value
で指定した数字を超えることをチェックします。
$field > $value
##greaterThanOrEqual##
$validator->greaterThanOrEqual($field, $value, $message = null, $when = null)
$value
で指定した数字以上であることをチェックします。
$filed >= $value
##lessThan##
$validator->lessThan($field, $value, $message = null, $when = null)
$value
で指定して数字未満であることをチェックします。
$field < $value
##lessThanOrEqual##
$validator->lessThanOrEqual($field, $value, $message = null, $when = null)
$valued
で指定した数字以下であることをチェックします。
$field <= $value
##equals##
$validator->equals($field, $value, $message = null, $when = null)
$value
で指定した数字と一致することをチェックします。緩やかな比較(==)が使われます。
$field == $value
##notEquals##
$validator->notEquals($field, $value, $message = null, $when = null)
$value
で指定した数字と一致しないことをチェックします。緩やかな比較(!=)が使われます。
$field != $value
##sameAs##
$validator->sameAs($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールドと一致することをチェックします。厳密な比較(===)が使われています。
$field === $secondField
##notSameAs##
$validator->notSameAs($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールドと一致することをチェックします。厳密な比較(!==)が使われています。
$field !== $secondField
##equalToField##
$validator-> equalToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールドと一致することをチェックします。緩やかな比較(==)が使われています。
$field == $secondField
##notEqualToField##
$validator->notEqualToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールドと一致することをチェックします。緩やかな比較(!=)が使われています。
$field != $secondField
##greaterThanToField##
$validator->greaterThanToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールドを超えることをチェックします。
$field > $secondField
##greaterThanOrEqualToField##
$validator->greaterThanOrEqualToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールド以上であることをチェックします。
$filed >= $secondField
##lessThanToField##
$validator->lessThanToFieldToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールド未満であることをチェックします。
$field < $secondField
##lessThanOrEqualToField##
$validator->lessThanOrEqualToField($field, $secondField, $message = null, $when = null)
バリデーション対象の配列の他のフィールド以下であることをチェックします。
$field <= $secondField
##containsNonAlphaNumeric##
$validator->containsNonAlphaNumeric($field, $limit = 1, $message = null, $when = null)
英数字が含まれているかどうかをチェックします。$limit
を指定すると、その回数だけ英数字が含まれていることを要求します。
alphaNumericとは違う正規表現が使われています。
$matches = preg_match_all('/[^a-zA-Z0-9]/', $check);
##date##
$validator->date($field, $formats = ['ymd'], $message = null, $when = null)
日付の形式かどうかをチェックします。$formats
をymd形式で指定することができます。
指定できる形式は以下のとおりです。
-
dmy
27-12-2006 or 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 -
ym
2006/12 or 06/12 -
y
2006
日付の区切りは-
(スペース) /
.
が使えます。
##datetime##
$validator->dateTime($field, $formats = ['ymd'], $message = null, $when = null)
dateとtimeの両方をチェックします。
形式は、dateメソッドでしていしたものに加えて、ISO8601
を指定することでISO8601形式を使用することができます。
##time##
$validator->time($field, $message = null, $when = null)
時刻の形式かチェックします。
具体的には、(HH:MM)
か、([H]H:MM[a|p]m)
の形式です。
##localizedTime##
$validator->localizedTime($field, $type = 'datetime', $message = null, $when = null)
地域化された日付形式化チェックします。
具体的には\Cake\I18n\Time
のメソッドを使用してチェックされます。
形式は以下の3つから選ぶことができます。
- datetime \Cake\I18n\Time::parseDateTime()`
- date \Cake\I18n\Time::parseDate()`
- time \Cake\I18n\Time::parseDate()`
##boolean##
$validator->boolean($field, $message = null, $when = null)
true, false, 0, 1, '0', '1'
に一致するかどうかチェックします。
文字列の0と1も許容します。
##decimal##
$validator->decimal($field, $places = null, $message = null, $when = null)
decimal型、つまり十進数小数であることをチェックします。
`$place'(小数の桁数)を指定できます。
- null => カンマ
.
が含まれている必要はない - true => 小数部分が0より大きいか、
float
かdouble
型であることが要求される。カンマ.
が含まれている必要がある。 - 1..N => 数字を指定すると、その桁数小数部分が存在することが要求される。
##email##
$validator->email($field, $checkMX = false, $message = null, $when = null)
$checkMX
を指定すると、MXレコードを含めてチェックします。
##ip##
$validator->ip($field, $message = null, $when = null)
IPv4または、IPv6の形式がどうかチェックします。
##ipv4##
$validator->ipv6($field, $message = null, $when = null)
##ipv6##
$validator->ipv6($field, $message = null, $when = null)
##minLength##
$validator->minLength($field, $min, $message = null, $when = null)
mb_strlenをしようして、$min
で指定した文字数以下かチェックします。
mb_strlen($check) >= $min
##maxLength##
$validator->maxLength($field, $max, $message = null, $when = null)
mb_strlenをしようして、$max
で指定した文字数以上かチェックします。
mb_strlen($check) <= $max
##minLengthBytes##
$validator->minLengthBytes($field, $min, $message = null, $when = null)
strlenをしようして、$min
で指定したバイト数以下かチェックします。
strlen($check) >= $min
##maxLengthBytes##
$validator->maxLengthBytes($field, $max, $message = null, $when = null)
strlenをしようして、$max
で指定したバイト数以上かチェックします。
strlen($check) <= $max
##numeric##
$validator->numeric($field, $message = null, $when = null)
is_numericを使用してチェックされているので、
16進数表記0x539
や1337e0
なども認められます。
##naturalNumber##
$validator->naturalNumber($field, $message = null, $when = null)
自然数かどうかを、正規表現を用いてチェックしています。
0は自然数に含みません。
/^[1-9][0-9]*$/
##nonNegativeInteger##
$validator->nonNegativeInteger($field, $message = null, $when = null)
0以上の整数か、つまり0を含む自然数かどうかチェックしています。
実際、参照先はnaturalNumberと同じく\Cake\Validation\Validation::naturalNumber()
です。
/^(?:0|[1-9][0-9]*)$/
##range##
$validator->range($field, array $range, $message = null, $when = null)
lengthBetween
と似ていますが、こっちは数字が有効の範囲化チェックします。
$range
で指定する数字は、float型もOKです。
##url##
$validator->url($field, $message = null, $when = null)
スキーマ、IP、ドメインネーム、パス、クエリー、フラグメントの部分に分けられて判定されます。
スキーマは省略されていても構いません。
##urlWithProtocol##
$validator->url($field, $message = null, $when = null)
前述のurl
と同じ参照先ですが、こちらはスキーマの指定が必須になります。
スキーマは以下の通りです。
http(s)/ftp(s)/file/news/gopher
##inList##
$validator->inList($field, array $list, $message = null, $when = null)
フィールドが$list
で指定された配列の要素の中にあるか、in_array
でチェックします。
strval
で文字列に変換してから比較してるので、int型を指定しても特に問題はありません。
(フォームから送られる数字は、通常文字列です。)
例
$validator->inList('fruit', ['apple', 'banana', 'lemon'])
'apple' => OK
'Kiwi' => NG
'APPLE' => NG
##uuid##
$validator->uuid($field, $message = null, $when = null)
UUIDは、一位となる識別子です。
8桁-4桁-4桁-12桁の16進数で構成されています。
##uploadedFile##
$validator->uploadedFile($field, array $options, $message = null, $when = null)
ファイル形式かどうか調べます。これは、\Psr\Http\Message\UploadedFileInterface
のインスタンスかどうかで判定しています。
$option
を指定すると、以下の更に以下を指定することができます。
-
types
ファイルの拡張子を指定する。 -
minSize
ファイルの最小バイト数を指定する。 -
maxSize
ファイルの最大バイト数を指定する。 -
optional
ファイルがオプションかどうか
##latLong##
$validator->latLong($field, $message = null, $when = null)
##latitude##
$validator->latitude($field, $message = null, $when = null)
##longitude##
$validator->longitude($field, $message = null, $when = null)
##ascii##
$validator->ascii($field, $message = null, $when = null)
##utf8##
$validator->utf8($field, $message = null, $when = null)
##utf8Extended##
$validator->utf8Extended($field, $message = null, $when = null)
##integer##
$validator->integer($field, $message = null, $when = null)
整数かどうかをチェックするので、fload型は受け付けません。
is_int
を使ってチェックしていますが、`フォームから来た洗の場合は常に文字列として扱われるため、
そのような場合には正規表現を用いてチェックされています。
if (!($value) || is_float($value)) {
return false;
}
if (is_int($value)) {
return true;
}
return (bool)preg_match('/^-?[0-9]+$/', $value);
##isArray##
$validator->isArray($field, $message = null, $when = null)
is_array
でチェックされています。
##isScaler##
$validator->isScaler($field, $message = null, $when = null)
is_scaler
でチェックされています。
##hexColor##
$validator->hexColor($field, $message = null, $when = null)
16進数文字が6回出現するかどうかでチェックしています。
##multipleOptions##
multipleOptions($field, array $options = [], $message = null, $when = null)
複数選択セレクトボックスは、配列で送られてくるので、その形式になっているかチェックします。
$options
は、以下の選択肢を指定することができます。
- in =>
in_array
で、特定の要素が存在するかチェックします。 - max => 指定された数を超える数選択されていることをチェックします。
- min => 指定された数未満選択されていることをチェックします。
- caseSensitive => tureを指定すると、inでチェックするとき、大文字小文字を無視します。
##hasAtLeast##
$validator->hasAtLeast($field, $count, $message = null, $when = null)
これは、hasManyまたはbelongsToManyにおける特別な配列のキー__ids
の数と比較するものです。
hasManyアソシエーションを保存しようとするとき、以下のような_ids
形式を使うことができます。
$data = [
'title' => '私の新しい記事',
'body' => '本文',
'user_id' => 1,
'comments' => [
'_ids' => [1, 2, 3, 4]
]
];
この_ids
の数が`$count'で指定したか数未満のとき、バリデーションエラーが発動します。
##hasAtMost##
$validator-> hasAtMost($field, $count, $message = null, $when = null)
フィールドの_ids
が$count
以下かどうかをチェックします。
##regex##
$validator->regex($field, $regex, $message = null, $when = null)
$regex
に、正規表現を指定します。