スライドショー

【PHP】CakePHPのvalidation機能の使い方

こんにちは!エンジニアのノムラです。

突然ですが、CakePHPのバリデーションの機能をみなさんはしっかり使いこなせていますか?

この記事では、

  • バリデーションでできること
  • バリデーションの使い方
  • バリデーションルール

といった、バリデーションについて基本的なことから、

  • エラー情報の取得
  • バリデーションが効かないときに確認したいこと

など、CakePHPのバリデーションについてわかりやすく解説していきたいと思います。

CakePHPのvalidation

CakePHPのバリデーション機能は、入力された値が指定されたルールに沿っているかをチェックしてくれる機能です。

validationでできること

入力された値のチェックを行ってくれるバリデーションですが、どのようなルールに沿ってチェックするのでしょうか?

例えば、入力項目に空がないかチェックしてくれたり、日付の形式が指定した形式通りになっているかを確認することができます。

また、あらかじめ用意されているルールで判定できない場合は、独自のルールをつくることができます。

validationの使い方

バリデーションは対象のモデルに対して記述します。
基本的な書き方は以下のようになります。

$validator->ルール名('カラム名');

ルール名には、あらかじめCakePHPで用意されているルール名をいれ、カラム名はチェックを行いたいカラム名を指定します。

例えば、空かどうかをチェックする「notEmpty」を「name」というカラム名に適用しようとすると、

$validator->notEmpty('name');

というようになります。

第二引数にメッセージを指定すれば、エラーメッセージを任意のものに変更することが出来ます。
詳しいエラーメッセージの出力方法に関しては、後ほど解説します。

使える!validationのルール一覧

では、数字のみを許可する「numeric」を例にサンプルコードを見ていきましょう。

まずはバリデーションルール記述部分です。
usersTableのカラムに対してチェックを行うため、usersTable.phpに記述します。

【usersTable.php】

namespace App\Model\Table;
use Cake\Validation\Validator;
use Cake\ORM\Table;

class usersTable extends Table{

  public function validationDefault(Validator $validator){
    $validator->numeric('name');
    return $validator;

  }
}

コントローラーでは、データがPOSTされ、バリデーションエラーがなかった場合に登録されるよう処理を行います。

【TestController.php】

namespace App\Controller;
use Cake\Controller\Controller;
use Cake\ORM\TableRegistry;

class TestController extends AppController{

  public function index(){
    $this->loadModel('users');
    $entity = $this->users->newEntity($this->request->data);
    if($this->request->is('post')) {
      if(!$entity->errors()) {
        //エラーなし、登録処理
      }
    }
    $this->set(compact('entity'));
  }
}

バリデーションのエラーは、$entity->errors()に格納されていきます。

ビューはFormヘルパーを使って以下のように作成します。

【index.ctp】

<?= $this->Form->create() ?>
  <?= $this->Form->text('name') ?>
  <?= $this->Form->button('送信') ?>
<?= $this->Form->end() ?>

バリデーションチェックでエラーがなかった場合のみ登録され、エラーがあった場合は登録されません。

CakePHPで用意されているバリデーションルールとして、よく使うものをまとめてみました。

ルール機能
notEmpty未入力をチェックする
allowEmpty空を許可する
numeric数字のみかチェックする
alphanumeric文字と数字のみかチェックする
range指定した範囲内の値かチェックする
greaterThan指定値より大きいかチェックする
lessThan
指定値より小さいかチェックする
time
時間のフォーマットをチェックする
minLength
指定した最小文字数を満たしているかチェックする
maxLength
指定した最大文字数以内かチェックする
isUniqueユニークか調べる

これ以外にもたくさんのルールがあるので調べてみてください。

独自のルールを作る

CakePHPでは用意されているルール以外にも、独自のバリデーションルールをつくることもできます。

独自のルールはテーブルに直接書かず、src\Model\Validationというディレクトリを作成して記述します。
今回はそこにCustomValidation.phpというファイルを作成し、そこに独自のルールを作りました。

サンプルコードで具体的な例を見ていきましょう。

【CustomValidation.php】

namespace App\Model\Validation;
use Cake\Validation\Validation;

class CustomValidation extends Validation {
  //独自のルール
  public static function postal_codeCustom($check) {
    return (bool)  preg_match('/^([0-9]{3})(-[0-9]{4})?$/i', $check);
  }
}

サンプルでは、郵便番号を正規表現でチェックするカスタムバリデーションを作成します。

このとき、作成するfunctionは「static」にするという点に注意してください。
「static」にしないとエラーがでてしまいます。

テーブルは以下のようになります。

【usersTable.php】

namespace App\Model\Table;
use Cake\Validation\Validator;
use Cake\ORM\Table;

class usersTable extends Table{

  public function validationDefault(Validator $validator){
    //プロバイダ設定
    $validator->setProvider('Custom', 'App\Model\Validation\CustomValidation');
    $validator->notEmpty('postal_code')
              ->add('postal_code', '', [
                       'rule' => ['postal_codeCustom'],
                        'provider' => 'Custom',
                        'message' => '郵便番号の形式が違います。']);

    return $validator;

  }
}

カスタムバリデーションを使う場合、$validator->setProvider(キー、値)メソッドを利用する。プロバイダのキーとして‘Custom’、値はCustomValidationのファイルパスを示すよう‘App\Model\Validation\CustomValidation’のように設定し、addで作成したカスタムバリデーションを追加します。

providerには、プロバイダ設定のとき指定したプロバイダのキーを入れてください。

バリデーションでエラーがあった場合、指定したエラーメッセージが返ってきます。

validationのエラー情報を取得

バリデーションでエラーがあった場合、エラー内容を取得して処理を行いたい場合があると思います。
エラーメッセージの設定方法や、エラーログの出力について解説します。

任意エラーメッセージを設定する

CakePHPには、多くのバリデーションルールが用意されていることを解説しましたが、それらのルールに対して任意のエラーメッセージを設定していくことも可能です。

指定したエラーメッセージを出力させてみましょう。

【usersTable.php】

namespace App\Model\Table;
use Cake\Validation\Validator;
use Cake\ORM\Table;

class usersTable extends Table{

  public function validationDefault(Validator $validator){
    $validator->maxLength('name', 6,'6文字以内で設定してください。');
    return $validator;
  }
}

最大文字数をこえていないかチェックするmaxLengthでは、第一引数にカラム名、第二引数に最大文字数を指定します。

第三引数には、任意のエラーメッセージを指定してください。

ビューは以下のようになります。

【index.ctp】

<?= $this->Form->create($entity) ?>
  <?= $this->Form->text('name') ?>
  <?= $this->Form->error('name') ?>//error()でバリデーションエラーを出力
  <?= $this->Form->button('送信') ?>
<?= $this->Form->end() ?>

ビューでバリデーションエラーのerror()を使う場合は、create()の第一引数にエンティティを渡す必要があります。

error()で指定したエラーメッセージを出力しているため、画面には「6文字以内で設定してください。」と出力されます。

エラーログを出力する

エラーログを出力する場合は、バリデーションエラーがあったときにログを出力する処理を加えます。

【TestController.php】

class TestController extends AppController{

public function index(){
  $this->user = TableRegistry::get('users');
  $entity = $this->user->newEntity($this->request->data);

    if($this->request->is('post')) {
      if(!$entity->errors()) {
        //エラーなし、登録処理
      }else{
        //エラーログ出力
        $this->log('validationErrors=' . var_export($entity->errors(), true));
      }
    }
    $this->set(compact('entity'));
}

ログを出力するファイルを指定していない場合は、logs/error.logに出力されます。

上のサンプルコードだと、ログは以下のように出力されました。

2018-04-20 07:26:23 Error: validationErrors=array (
  'name' => 
  array (
    'maxLength' => '6文字以内で設定してください。',
  ),
)

バリデーションのエラーを出力していると、問題があったときに役に立ちます
ぜひ実践してみてください。

validationが正しく動作しないとき

正しく記述しているはずなのに、バリデーションが効かないエラーメッセージが出力されないというときがあるかと思います。

その場合以下のポイントをもう一度確認してみてください。

エラーメッセージが出力されない

エラーメッセージが出力されない場合、Viewファイルの$this->Form->create()に$entityが渡されているか確認しましょう。

任意のエラーメッセージを出力するときにも解説しましたが、エンティティをcreate()に渡していなければエラーメッセージは出力されません

エラー内容がViewファイルで使える状態になっているか確認してみましょう。

バリデーションが動作しないとき

バリデーションが動作しない場合は、コントローラー側でモデル名を間違えていないかを確認しましょう。

バリデーションでテーブル名を記述するとき、誤ったテーブルを指定していませんか?
当たり前ですが、指定するテーブルが変わるとバリデーションも効かなくなります。

簡単なミスですが、意外とよくあるのでもう一度確認してみてください。

バリデーションは、ルールの指定や引数などが多く慣れるまでは、簡単なミスでエラーがでてしまうということがあると思います。

自分の書いたコードをよく見直し、間違いはないかしっかり確認しましょう。

まとめ

CakePHPのバリデーションの使い方について、よく使うルールの解説や、エラーの出力方法などについて解説しました。

バリデーションの機能は、開発でも非常によく使う重要な機能です。
しっかりマスターしましょう!

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

ノムラ

ノムラ

WEBエンジニアをやっています。
プログラミング初心者にもわかりやすく解説ができるよう頑張ります。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説