スキップしてメイン コンテンツに移動

CakePHPのバリデーションルールまとめ

CakePHPのモデル内のバリデーションで利用できるバリデーションルールをまとめました。いちいちコメント付けてたらとんでもない時間がかかってしまいましたが、不可解な部分はソースコードを読んで処理を追ったり、サンプルを作って確認したので、cookbookより濃厚なコメントができたと思いますがどうでしょうかね。個人的には色々不明な部分が晴れた気がしたのでスッキリです! なお確認したバージョンは2.4.6です。



バリデーションの書き方

バリデーションのルールはモデルに書きます。
モデル内のプロパティとして設定する方法と、後付けで登録する方法(version2.2以降)がありますが、ここではプロパティとして設定する方法を紹介します。

基本形として1つのルールをつける場合は以下のようにします。
Class Hoge extends AppModel {
    public $validate = array(
        'username'=> 'alphaNumeric',
        'email'=> 'email',
    );
}

2つのルール以上のルールをつける場合は、ルールを配列にします。
Class Hoge extends AppModel {
    public $validate = array(
        'username'=> array(
            'alphaNumeric'=> array(
                'rule'=> 'alphaNumeric',
            ),
            'minLength'=> array(
                'rule'=> array('minLength', 8),
            ),
        ),
        'email'=> 'email',
    );
}


バリデーションルールの種類

CakePHPには、デフォルトで多くのバリデーションルールが用意されています。
このルールを組み合わせてバリデーションを行う事で、少ない手数でバリデーション処理が行えますし、自前で実装しない分、間違いの少ないバリデーションが行えます。

alphaNumeric
データが文字と数字のみである事を検証する。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  'rule'=> 'alphaNumeric',
              ),
          ),
      );
    
between
データの文字数を設定した最小、最大の間にある事を検証する。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  'rule'=> array('between', 5, 10),
              ),
          ),
      );
    
上記の例では5以上10以下の文字数の場合のみTrueを返す。
blank
データがスペース、タブ、改行コード、空白のいずれかである事を検証する。Formヘルパーからフォームを作成した時はallowEmptyをtrueにしていないと空白を入力できないので注意。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  'rule'=> 'blank',
                  'allowEmpty'=> true,
              ),
          ),
      );
    
boolean
データがtrueかfalseであるか検証する。bool値(true/false)、数字の0/1、文字の"0"/"1"の場合のみTrueを返す。文字列の"true"/"false"は常にFalseを返すのでフォームからTrueを送っても文字列なので検証はうまく通らない。
public $validate = array(
          'flg'=> array(
              'validate1'=> array(
                  'rule'=> 'boolean',
              ),
          ),
      );
    
cc
クレジットカードのバリデーション。第2引数は色んなクレジットカードや銀行カードがプリセットされているので、それらを配列でセットするか、全てのカードタイプをチェックする"all"かメジャーなクレジットカードだけをチェックする"fast"が選べる。 また、第3引数でtrueをセットすると、正規表現に加えてLuhnアルゴリズムによるカード番号の妥当性もチェックする。 第4引数に正規表現をセットすると、独自の正規表現でバリデーションする。この場合はカードタイプによる正規表現を無視する。
public $validate = array(
          'credit1'=> array(
              'validate1'=> array(
                  // allで全てのカードのバリデーションする(Luhnアルゴリズムチェックなし、独自正規表現なし)
                  'rule'=> array('cc', 'all'),
              ),
          ),
          'credit2'=> array(
              'validate1'=> array(
                  // fastでメジャーなカードのバリデーションする(Luhnアルゴリズムチェックなし、独自正規表現なし)
                  'rule'=> array('cc', 'fast'),
              ),
          ),
          'credit3'=> array(
              'validate1'=> array(
                  // 引数でバリデーションするカードの種類を選ぶ(Luhnアルゴリズムチェックなし、独自正規表現なし)
                  'rule'=> array('cc', array('amex', 'visa', 'mc', 'jcb'),
              ),
          ),
      );
    
comparison
数字の比較検証する。第2引数には、比較する際のオペレーターを設定。第3引数には比較対象の数字をセットする。 オペレーターの種類
>, isgreater
より大きい
<, isless
より小さい
>=, greaterorequal
以上
<=, lessorequal
以下
==, equalto
等しい
!=, notequal
等しくない
文字の比較はできないので別途strcmpなどで比較するカスタムバリデーションを作成するか、独自バリデーションクラスを作ってuserDefinedルールで検証する。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  // 10以上の場合にTrue
                  'rule'=> array('comparison', '>=', 10),
              ),
          ),
      );
    

custom

自作の正規表現でバリデーションする。正規表現をセットされていないとエラーを出す。
文字の比較はできないので別途strcmpなどで比較するカスタムバリデーションを作成する。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  // 先頭がabcで始まっていればTrue
                  'rule'=> array('custom', '/^abc/'),
              ),
          ),
      );
    

date

データが日付であるか検証する。日付のセパレーターとして利用できるのは、「-」「 (スペース)」「/」「.」の4種類。日付のフォーマットで利用できるのは以下の通り。
dmy
日月年の順で並んでいる数字で表現された日付
mdy
月日年の順で並んでいる数字で表現された日付
ymd
年月日の順で並んでいる数字で表現された日付
dMy
日月年の順で並んでいて、月が英語で表現された日付(英語の月はフルスペル、3文字の略どちらでも良い)
Mdy
月日年の順で並んでいて、月が英語で表現された日付(英語の月はフルスペル、3文字の略どちらでも良い)
My
月年の順で並んでいて、月が英語で表現された日付(英語の月はフルスペル、3文字の略どちらでも良い)
my
月年の順に並んでいる数字で表現された日付
ym
年月の順に並んでいる数字で表現された日付
y
年だけの日付
年に関しては、いずれのフォーマットでも4桁、もしくは下2桁どちらでもよい。
public $validate = array(
          'date'=> array(
              'validate1'=> array(
                  // yyyy-mm-ddもしくは、yy-mm-ddのフォーマットで検証する
                  'rule'=> array('date', 'ymd'),
              ),
          ),
      );
    

datetime

日付と時間をスペースで連結したデータであるか検証する。日付のチェックに関しては、同じバリデーションルールのdateと同じフォーマットを指定する(というか内部ではdateのルールそのものを使ってバリデーションしている)。
時間は、24時制表記、AM/PMを使った12時制表記、のどちらも利用できる。秒のバリデーションはできない
public $validate = array(
          'datetime'=> array(
              'validate1'=> array(
                  // yyyy-mm-dd HH:MMもしくは、yy-mm-dd HH:MM AM/PMのフォーマットで検証する
                  'rule'=> array('datetime', 'ymd'),
              ),
          ),
      );
    
「00:05」は24時制では深夜0時5分となってTrueとなるが、「00:05 AM」はfalseになる(バグ?)

decimal

実数であるかの検証を行う。正負の符号、有効桁数を表すEが付いていてもチェックできる。
public $validate = array(
          'float'=> array(
              'validate1'=> array(
                  // 実数チェック
                  'rule'=> array('decimal'),
              ),
              'validate2'=> array(
                  // 小数点以下の桁数を第2引数に指定
                  'rule'=> array('decimal', 3),
              ),
          ),
      );
    

email

メールアドレスの検証を行う。
第2引数にtrueをセットすると、MXレコードやDNSなどをチェックしてメールサーバーが存在するかもチェックする(時間かかりそう)。
第3引数に正規表現をチェックするとその正規表現を利用してバリデーションする。
public $validate = array(
          'mail'=> array(
              'validate1'=> array(
                  // 正規表現による簡単なメールチェック。
                  'rule'=> array('email'),
              ),
              'validate2'=> array(
                  // 正規表現とネームサーバー問い合わせによるメールチェック。
                  'rule'=> array('email', true),
              ),
          ),
      );
    

equalTo

データの型、内容を検証する。内部では「===」でチェックしているだけ。strcmpでも実現できるが、strcmpだと、"111"と111は同じと判定される。PHPの型の自動変換の問題。
public $validate = array(
          'str'=> array(
              'validate1'=> array(
                  // strが文字列の'12345'である事を検証する
                  'rule'=> array('equalTo', '12345'),
              ),
          ),
      );
    

extension

アップロードしたファイル拡張子をセットした拡張子の配列の中に存在するか検証する。
public $validate = array(
          'str'=> ar$validate = array(
          'file'=> array(
              'validate1'=> array(
                  // ファイルが'mp3', 'mp4', 'aac', 'ogg', 'mov'のいずれかか検証する
                  'rule'=> array('extension', array('mp3', 'mp4', 'aac', 'ogg', 'mov')),
              ),
          ),
      );ray(
              'validate1'=> array(
                  // strが文字列の'12345'である事を検証する
                  'rule'=> array('equalTo', '12345'),
              ),
          ),
      );
    

fileSize

アップロードしたファイルのファイルサイズを第3引数と比較検証する。第2引数には'<'や'>'などのオペレーターをセットする。セットできるオペレーターの種類はcomparisonバリデーションルールと同じなのでそちらを参照の事。
また第3引数は1MBや500KBなどのように指定できる。
public $validate = array(
          'file'=> array(
              'validate1'=> array(
                  // ファイルが2MBより大きいか検証する
                  'rule'=> array('fileSize', 'isgreater', '2MB'),
              ),
          ),
      );
    

inList

データの内容が、第2引数にセットした配列の中に存在するか検証する。
恐らくセレクトボックスやラジオボタンなど、入力値が決まっている場合に利用すると便利でしょうか。
第3引数をtrueにすると型チェックも行う。内部ではin_array関数を通しているだけ。
public $validate = array(
          'list'=> array(
              'validate1'=> array(
                  // 入力値がonかoffの場合にTrueとなる
                  'rule'=> array('list', array('on', 'off')),
              ),
          ),
      );
    

ip

データがIPアドレスかどうか検証する。第2引数を省略した場合はv4、v6どちらの検証も行う。
public $validate = array(
          'ip'=> array(
              'validate1'=> array(
                  // IPアドレスがv4であるか検証する
                  'rule'=> array('ip', 'IPv4'),  // IPV4の指定は大文字小文字どちらでも良い
              ),
          ),
      );
    

isUnique

入力値がモデルで扱うテーブルの中に存在しないか確認する。
データを検証する際にDB接続してカラムを走査します。
public $validate = array(
          'username'=> array(
              'validate1'=> array(
                  // usernameがユニークかどうか検証する
                  'rule'=> array('isUnique'),
              ),
          ),
      );
    

luhn

入力値をLuhnアルゴリズムで検証する。LuhnアルゴリズムについてはWikipediaを参照のこと。
第2引数を省略するとノーチェックでTrueを返すので、利用する場合は必ず第2引数にtrueをセットする。
public $validate = array(
          'luhn'=> array(
              'validate1'=> array(
                  'rule'=> array('luhn', true),
              ),
          ),
      );
    

maxLength

入力値が指定した文字数以下であることを検証する。どのルールでも言える事だが、maxLengthはmaxlengthでもMAXLENGTHでもいい。
public $validate = array(
          'str'=> array(
              'validate1'=> array(
                  // 入力値を最大10文字に制限する
                  'rule'=> array('maxLength', 10),
              ),
          ),
      );
    

mimeType

アップロードしたファイルのMIMEタイプを検証する。第2引数に検証するMIMEタイプを配列でセットする。
内部でfinfo_openとmime_content_typeを使っているが、finfo系の関数はPECL拡張ライブラリなので存在しない可能性もある。その場合はmime_content_typeを代替関数として利用するが、こちらの関数は非推奨なので存在しない可能性もある。両方存在しない場合はたらい回しにされた挙句、Falseとなる。
ちなみにfileinfoのPECL拡張ライブラリを後から追加する方法は過去にmcryptを追加する方法を記事にしてありますが、同じ方法で何とかなります(と思います)。
public $validate = array(
          'file'=> array(
              'validate1'=> array(
                  'rule'=> array('mimeType', array('image/jpeg', 'image/gif', 'image/png', 'image/bmp')),
              ),
          ),
      );
    

minLength

入力値が指定した文字数以上である事を検証する。
public $validate = array(
          'str'=> array(
              'validate1'=> array(
                  // 文字数が5文字以上ならTrue
                  'rule'=> array('minLength', 5),
              ),
          ),
      );
    

money

通貨を示す文字列か検証する。
具体的には通貨記号+数字、もしくは数字+通貨記号、数字のみかのいずれかのパターンであるかを検証する。ちなみに内部ではPHPにプリセットされているpreg_matchの文字プロパティを使ってマッチングしている。
第2引数には通貨記号が数字の右に来るか左に来るかを指定する。日本円¥で検証する場合は'left'をセットする。
public $validate = array(
          'jappanesemoney'=> array(
              'validate1'=> array(
                  // 通貨記号が左に来る場合は第2引数を省略できる
                  'rule'=> array('money'),
              ),
          ),
      );
    

multiple

セレクトボックスで複数の入力値を選んだ場合の検証をする。入力した配列の値の個数で最大値、最小値チェック+入力値毎にinListルールの検証をするニュアンスです。
第2引数は配列で、'in'、'min'、'max'をセットします。必須項目はなく、単純に配列内の入力値の個数だけを検証することもできます。
ちなみにcookbookには書いてないですが第3引数にtrue/falseをセットすることもできて、trueの場合は型チェックも行います。デフォルトはtrueです。
public $validate = array(
          'select'=> array(
              'validate1'=> array(
                  // フォームからの入力値は文字扱いなので、第3引数をfalseにすることで検証できる
                  'rule'=> array('multiple', array('in'=> array(1, 2, 3, 4, 5, 6), 'min'=> 1, 'max'=> 3), false),
              ),
          ),
      );
    

notEmpty

入力値が空か検証する。
なかなか使いどころが難しく、他にルールを設定している場合は自動的にnotEmptyの制限がつくのであえてルールを書く必要はない(と思ってます)。空かどうかのチェックだけならもっと簡潔に書ける。
$this->Form->select()の'multiple'=> trueになっているフォームの入力値のバリデーションにこのルールを使うと常にfalseになるので使わない。
public $validate = array(
          'string'=> array(
              'validate1'=> array(
                  'rule'=> 'notEmpty',
              ),
          ),
      );
/*
 * 簡単に書くとこうなる
*/
public $validate = array(
          'string'=> array(
              'allowEmpty'=> false,
          ),
      );
    

numeric

入力値が数字であることを検証する。
内部ではis_numericを通しているだけ。
public $validate = array(
          'str'=> array(
              'validate1'=> array(
                  'rule'=> 'numeric',
              ),
          ),
      );
    

naturalNumber

入力値が自然数かどうかの検証をする。0は自然数ではないと学校では教えられますが、第2引数にtrueをセットすることで0も含めることができます。
public $validate = array(
          'num'=> array(
              'validate1'=> array(
                  // 0を含めた正の整数(自然数)かどうか検証する
                  'rule'=> array('naturalNumber', true),
              ),
          ),
      );
    

phone

入力値が電話番号かどうか検証する。第3引数に国を指定して検証できますが、アメリカとカナダしか対応していないようです。従って、日本の電話番号を検証する際は第2引数に正規表現をセットして検証する事になります。
public $validate = array(
          'tel'=> array(
              'validate1'=> array(
                  // アメリカ国内の電話番号で検証する。
                  // 日本国内の電話番号に対応した正規表現は電話番号のフォーマットに詳しくない私が書くわけにはいきません:-P
                  'rule'=> array('phone', null, 'us'),
              ),
          ),
      );
    

postal

入力値が郵便番号か検証する。こちらもphoneルールと同じく国番号を第3引数にセットすることでその国のフォーマットが選べますが、残念ながら日本は入っていませんでした。
対応しているのは、イギリス(uk)、カナダ(ca)、イタリア(it)、ドイツ(de)、ベルギー(be)、アメリカ(us)です。
public $validate = array(
          'zip'=> array(
              'validate1'=> array(
                  // 日本の郵便番号用の正規表現で検証する
                  'rule'=> array('postal', '/^[1-9][0-9]{2}-?[0-9]{4}$/'),
              ),
          ),
      );
    

range

入力値が指定した範囲内の数字か検証する。入力値が数字ではない場合はfalseになる。
第2引数に最小値、第3引数に最大値をセットする。どちらか、もしくはどちらも省略した場合は、PHP上で有効な有限値であるかをis_finite関数を使ってチェックする。
最大値だけ、最小値だけのチェックはできない模様。
public $validate = array(
          'num'=> array(
              'validate1'=> array(
                  // 入力値が5より大きく(以上ではない)、100より小さい(以下ではない)か検証する。
                  'rule'=> array('range', 5, 100),
              ),
          ),
      );
    

ssn

入力値がソーシャルセキュリティ番号(社会保障番号)かどうか検証する。日本にはこの手の番号はまだ存在していませんのであまり利用する事はないですが、マイナンバー制度が2016年1月から運用されることになった(てか今知った)ので、身分を証明する番号として浸透するでしょう。
public $validate = array(
          'str'=> array(
              'validate1'=> array(
                  'rule'=> array('ssn', null, 'us'),
              ),
          ),
      );
    

time

入力値が時間を表す文字列かどうかを検証する。バリデーションできるのは、24時制の時間:分(HH:MM)もしくは12時制の時間:分(am/pm HH:MM、もしくはHH:MM[A|P]M)のフォーマットで、秒はバリデーションできません。自前の正規表現を通すこともできません。
public $validate = array(
          'time'=> array(
              'validate1'=> array(
                  'rule'=> 'time',
              ),
          ),
      );
    

uploadError

ファイルのアップロードが正常にできたか検証する。
public $validate = array(
          'file'=> array(
              'validate1'=> array(
                  'rule'=> 'uploadError',
              ),
          ),
      );
    

url

入力値がURLかどうか検証する。第2引数をtrueにすることで、検証対象のプロトコルをhttp、https、ftp、ftps、sftp、file、news、gopherに制限します。
public $validate = array(
          'string'=> array(
              'validate1'=> array(
                  // http://example.com/users/edit/1を厳格にチェックする場合
                  'rule'=> array('url', true),
              ),
          ),
      );
    

userDefined

入力値を独自のバリデーションクラスを使って検証する。
class myValid {
    // 文字列'foobar'と比較して同じかどうかをtrue/falseで返す関数
    function check($str1){
        return !(bool)strcmp($str1, 'foobar');
    }
}

public $validate = array(
          'file'=> array(
              'validate1'=> array(
                  // myValidクラスのcheck関数を使って検証する。第1引数に入力値が入る
                  'rule'=> array('userDefined', 'myValid', 'check'),
              ),
          ),
      );
    

uuid

入力値がuuidであるかどうか検証する。uuidとは重複が(理論上)起こりえない一意な文字列の事。
public $validate = array(
          'id'=> array(
              'validate1'=> array(
                  'rule'=> 'uuid',
              ),
          ),
      );
    


多かったなぁ。


コメント

このブログの人気の投稿

[VB.NET]オレオレ証明書でSSL通信するための短絡的な解決法

VB.NETソフトウェアでサーバーと通信することはよくある事だと思いますが、最近はHTTPを使って明けっ広げに刺しに行くよりHTTPSを使って暗号化してこそこそやった方が時代の流れに即した感じですよね(違うか)。 いちいちテスト環境でSSL証明書を用意するのも面倒だということで、セキュリティ的には全くよろしくない方法で迂回できるので紹介します。

[JS]Canvasでよく使う描画テクまとめ

HTMLで画像をいじくりたい時は、canvasを利用して編集するのは一般的ですが、WindowsストアアプリではHTML+CSS+JSでのアプリ開発ができる事もあって、簡単な画像編集であれば、C#やVBを使うより分かりやすいし資料が多く、C++でDirectXをガリガリ書くよりお手軽。入出力もファイルピッカーを使えば簡単に実装できます。今回は、Windowsのコードではなく、Canvasを利用する時のJavaScriptを使いどきに合わせてまとめていきます。

curl の基本的な使い方 -設定編-

今回のcurl TIPSは、curlをより日常的に使っていくためのHow toです。curlには、数多くのオプションが用意されていて、それらを組み合わせる事で様々な事が楽になるでしょう。サービス監視の自動化などにはまさにcurlの得意分野です。 今回は、curlを更に自分のものにしていくために大事なカスタマイズの部分を解説します。