【CakePHP入門】バリデーションの使い方を解説!(validation)

こんにちは。ライターの亀田です。

Webでアプリケーションを作るとき、フォームで電話番号やメールアドレスなどの入力処理を作ることはよくあります。

しかし、普通のinputタグにデータが入力された際に、値が適切かチェックする仕組みがついていません

こんな時CakePHPのValidatorクラスを用いれば、実に簡単に値をチェックをすることが可能です。

ここでは、

・validationとは
・validationの使い方

で、その仕組みについて説明し、

・Validatorの主なメソッド
・バリデーションルールの指定方法

で、具体的なサンプルを通して説明します。

validationとは

バリデーション(validation)とは、入力されたデータが要求された仕様にそって適切に記述されているかどうかをチェックすることを言います。

たとえば、メールアドレスを入力する際には、〇〇@××.△△のような形式になっていればOKです。

しかしそれ以外の形式であれば、そのデータが不適切であると判断する必要があります。

CakePHPには、もともとこのバリデーションの仕組みがあり、チェックを簡単に行えるのです。

validationの使い方

Validatorクラスとは

CakePHPでは、バリデーションによる入力チェックの仕組みを使用するために、Validatorというクラスが用意されています。

このクラスは、入力に対し独自のルールを適用するための仕組みです。

では、実際にサンプルを使用して解説していくことにしましょう。

そのためには、まずテーブルを作り、それに合わせてbakeを使って、コードを自動生成し、それをもとに解説していきます。

まずはMySQLで、以下のテーブルを作ってみてください。

CREATE TABLE persons (
  id         int NOT NULL AUTO_INCREMENT,
  name       varchar(128) NOT NULL,
  age        int NOT NULL,
  tel        varchar(16) NOT NULL,
  zip        varchar(8) NOT NULL,
  address    varchar(256) NOT NULL,
  mail       varchar(128) NOT NULL,
  PRIMARY KEY(id)
) 

これは、名簿のフォーマットで、その人の名前、年齢などの属性をまとめて保存します。

ここで特にチェックしたいのが、郵便番号、電話番号、メールアドレスの形式です。

なお、CakePHPでSQLを用いるには準備が必要です。以下を参考にしてみてください。

【CakePHP入門】SQL(データベース)の基本を理解しよう!
更新日 : 2019年3月10日

Validatorを作成する

続いて、これをもとにbakeで、プロジェクトを作ってみましょう。

bin\cake bake all persons

すると、コードが自動生成されます。

なお、bakeに関しては、以下で詳しく説明しています。詳しくはこちらを参考にしてみて下さい。

【CakePHP入門】bakeの使い方
更新日 : 2019年4月20日

処理が終わったら、試しに、

localhost/[プロジェクト名]/persons/

にアクセスしてみてください。以下のような画面になります。

pic1

これは、personsテーブルで作った、名前、年齢、住所などがはいった名簿のようなものです。

pic2

この画面の左側に、「New Person」というリンクがあります。これをクリックすると、入力画面に遷移します。

pic3

ここでは、新しい人物の名前を入力できます。

ところで、この部分のvalidationを行うには、以下のソースで行います。

/src/Model/Table/PersonsTable.php

<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class PersonsTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('persons');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');
    }
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->scalar('name')
            ->requirePresence('name', 'create')
            ->notEmpty('name');

        $validator
            ->integer('age')
            ->requirePresence('age', 'create')
            ->notEmpty('age');

        $validator
            ->scalar('tel')
            ->requirePresence('tel', 'create')
            ->notEmpty('tel');

        $validator
            ->scalar('zip')
            ->requirePresence('zip', 'create')
            ->notEmpty('zip');

        $validator
            ->scalar('address')
            ->requirePresence('address', 'create')
            ->notEmpty('address');

        $validator
            ->scalar('mail')
            ->requirePresence('mail', 'create')
            ->notEmpty('mail');

        return $validator;
    }
}

validationDefaultメソッドで、バリデーションを行っています。

ここを試しに、以下のように変えてみてください。

validationDefault及び、その周辺の変更

 …(略)…
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->scalar('name')
            ->requirePresence('name', 'create')
            ->notEmpty('name','input name!');

        $validator
            ->integer('age')
            ->requirePresence('age', 'create')
            ->notEmpty('age');

        $validator
            ->scalar('tel')
            ->requirePresence('tel', 'create')
             ////電話番号形式のチェック ////
            ->notEmpty('tel','required tel')
            ->add('tel', 'custom',[
                'rule' =>[$this, 'tel_check'],
                'message' => 'invalid tel'
            ]);
            ////////////////////////////////

        $validator
            ->scalar('zip')
            ->requirePresence('zip', 'create')
            // 郵便番号番号形式のチェック //
            ->notEmpty('zip','required zip')
            ->add('zip', 'custom',[
                'rule' =>[$this, 'zip_check'],
                'message' => 'invalid zip'
            ]);           
            ////////////////////////////////

        $validator
            ->scalar('address')
            ->requirePresence('address', 'create')
            ->notEmpty('address');

        $validator
            ->scalar('mail')
            ->requirePresence('mail', 'create')
            ////メール形式のチェック ////
            ->notEmpty('mail', 'required mail')
            ->add('mail', 'validFormat', [
            'rule' => 'email',
            'message' => 'E-mail must be valid'
            ////////////////////////////
        ]);

        return $validator;
    }
    //    電話番号フォーマットのチェック
    public function tel_check($value, $context)
    {
        //boolで返さないとエラー
        return (bool) preg_match('/^[0-9]{2,5}-?[0-9]{2,5}-?[0-9]{2,5}$/', $value);
    }
    //    郵便番号フォーマットのチェック
    public function zip_check($value, $context)
    {
        //boolで返さないとエラー
        return (bool) preg_match('/^([0-9]{3})(-[0-9]{4})?$/i', $value);
    }
 …(略)…

これで、郵便番号、電話番号、およびメールアドレスに不適切な値が入力されると、エラーが発生します。

pic4

実に簡単に設定できることが分かります。

Validatorの主なメソッド

プログラムについて説明する前に、Validatorクラスについて説明します。

Validatorクラスには次に紹介するようなメソッドがあり値の評価が出来ます。

それらを順に紹介していきましょう。

値が空かどうかのチェック

指定したフィールドの値が空かをチェックすることが可能です。

allowEmptyは空の値を許可し、notEmptyは逆に空なら許可しません。

$validator->allowEmpty( フィールド名 );

notEmptyでは、ルールに違反して空白だった場合にメッセージを表示することも可能です。

$validator->notEmpty( フィールド名 );
$validator->notEmpty( フィールド名 ,メッセージ);

フィールドのチェック

以下のようにすると指定したフィールドがあるどうかをチェックすることも可能です。

$validator->hasField( フィールド名 );

フィールドの存在チェック

また、以下のようにすると指定したフィールドに、NOT NULL相当にし、なおかつ必須項目にします。

$validator->requirePresence( フィールド名 );

バリデーションルールの追加

独自のルールを追加できます。プログラマーが自ら定義することも可能です。

$validator->add( フィールド名 , ルール名 ); 
$validator->add( フィールド名 , ルール名 , 配列 ); 
$validator->add( フィールド名 , 配列 , 配列 );

特に大事なのはこのメソッドです。以下、具体例を基に詳細を説明していくことにしましょう。

バリデーションルールの指定方法

以上から、このサンプルでは、メール、郵便番号、電話番号のチェックにaddメソッドを使っています。

このルールには、CakePHPにもともと用意されているものとそうでないものがあります。

メールアドレス

メールアドレスは、もともと用意されているルールを使うことができます。

            
->notEmpty('mail', 'required mail')
->add('mail', 'validFormat', [
      'rule' => 'email',
      'message' => 'E-mail must be valid'
    ]);

notEmptyで、ここを空白にしてはいけないというルールを設定しています。

同時に、値が入力されていない場合には、「required mail」というメッセージが表示されるよう設定されています。

次に形式チェックですが、「 'rule' => 'email」とするだけでいいのです。

これは決まり文句のようなものだと思ってください。

最後にメッセージを定義します。形式チェックが不適切であれば、「E-mail must be valid」と表示されます。

郵便番号

次に、郵便番号を見てみましょう。

            
->notEmpty('zip','required zip')
->add('zip', 'custom',[
    'rule' =>[$this, 'zip_check'],
    'message' => 'invalid tel'
    ]);

考え方はemailと同じですが、こちらのほうはメールと違い、CakePHPにもともと用意されているルールは使っていません

validatorで評価したい形式をすべてCakePHPの側で用意しているわけではありません。

そのため独自に追加することが可能なのです。

ここではzip_checkというメソッドを呼び出して、値の評価を行っています。

このメソッドは、PHPのpreg_match関数を用いて、正規表現で郵便番号の値かどうかをチェックしています。

なお、preg_matchに関しては以下で詳しく説明していますので参考にしてみてください。

PHPで正規表現入門!7分で書き方・チェッカーツールの使い方を学ぼう
更新日 : 2019年5月21日
    
public function zip_check($value, $context)
{
    //boolで返さないとエラー
    return (bool) preg_match('/^([0-9]{3})(-[0-9]{4})?$/i', $value);
}

このように、正規表現を用いれば、どのような形式のチェックもできるのです。

電話番号

電話番号も、やり方は郵便番号の場合と同じです。

            
->notEmpty('tel','required tel')
->add('tel', 'custom',[
       'rule' =>[$this, 'tel_check'],
       'message' => 'invalid tel'
       ]);

こちらは、tel_checkというメソッドでチェックをしています。

以上で、簡単に、メールアドレス、郵便番号、電話番号のチェックができるようになりました。

URL・IPアドレス

最後に、参考までに、正規表現によるマッチングを行うpreg_matchで、
URLおよびIPアドレスのチェックをしたい場合の記述方法を紹介しておきましょう。

URL

/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i

IPアドレス

/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/

このほかにも、正規表現を用いれば様々な形式を簡単にチェックできます。

ちなみに、正規表現そのものについてもう少し学びたい方は以下を参考にしてみてください。

【PHP入門】正規表現で検索・抽出・置換する5つの関数を使い倒せ!
更新日 : 2019年5月11日

まとめ

ここでは、CakePHP3のValidationクラスを、以下のような流れで説明してきました。

・validationとは
・validationの使い方
・Validatorの主なメソッド
・バリデーションルールの指定方法

これらは、少しでも実用的なWebアプリを作るときには、必ず必要となる知識です。

しかし、使用方法は決して難しくありません

ぜひ、この記事を参考にして、どんどん応用してみて下さい。

最後まで挫折しないマンツーマンレッスン

侍エンジニア

挫折の多いと言われるプログラミングの習得においては、一人ひとりに合ったレッスンで自分のペースで学んでいくことが何よりも大事であり、「侍エンジニア」ではプロのエンジニアが専属マンツーマン指導。だからこそやり遂げることができます。

「自分のスタイルや目的に合わせて学習を進めたいな」とお考えの方は、ぜひチェックしてみてください。

無料体験レッスンはこちら

書いた人

亀田

エンジニアとして独自の製品やサービスを開発する傍ら、エンジニア教育にも力を入れています。企業研修や専門学校での非常勤講師もしながら、独自の言語学習サイト「一週間でわかるシリーズ」を運営し、エンジニアになりた人をサポートする活動をライフワークにしています。
【一週間で学べるシリーズ】
http://sevendays-study.com/

おすすめコンテンツ

まずはここから!初心者でも1から学べるプログラミング入門カリキュラム

転職成功で受講料0円!あなたもプログラミングを学んでエンジニアデビュー