エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


CakePHPのバリデーションを入力値・項目の条件によって変える方法を解説

   

CakePHPで入力値によってバリデーションを切り替える

 

CakePHP 2でバリデーションを条件によって切り替える方法

 
入力フォームから入力された項目によって、バリデーション(入力チェック)の内容を変えたい、という場面があると思いますが、その方法を CakePHPで実装する方法を解説します。
 
対象バージョン:CakePHP2系(CakePHP 2.2以上)
 
参考サイト
https://book.cakephp.org/2.0/ja/models/data-validation.html#id11
 
 

条件によってバリデーションの内容を変える具体的な例

 
想定している具体的なイメージは下記のような感じです。
 
「連絡手段を選択し、選択した連絡手段の連絡先の情報を入力してください。」
 
01_CakePHPのバリデーションを入力値・項目の条件によって変える方法を解説
 
上記の入力フォームで、「連絡手段」の選んだ選択肢によって、「連絡先情報」の入力内容が変わるため、それに合わせて「連絡先情報」のバリデーションの内容を変更する必要があります。
 
 「連絡手段:電話」 の場合は、電話番号チェック
 「連絡手段:メール」の場合は、メールアドレスチェック
 「連絡手段:郵送」 の場合は、郵便番号チェック
 「連絡手段:その他」の場合は、必須チェックのみ
 
 

CakePHPで unsetを利用して入力値を条件としてバリデーションを切り替える具体的なソースコードと解説

 

バリデーションを切り替える処理の実装手順

 
実装の手順としては以下の通りです。
 
1.Modelに、必要なバリデーションを記述します。
2.Controllerに、条件よって使わないバリデーションを削除する処理を記述します。
 
 

1.Modelに、必要なバリデーションを記述

 
では、具体的なソースコードを確認していきます。
 
まず、Modelに記述するバリデーションの内容です。
コメントを書いていますが、必須チェックのほか、電話番号、メールアドレス、郵便番号の入力チェックを行うバリデーションを記述しています。
 

  public $validate = array(
    'contact_number' => array(
      // 必須チェック
      'notEmpty' => array(
        'rule' => 'notEmpty',
        'allowEmpty' => false,
        'message' => 'アカウントIDが入力されていません'
      ),

      // 電話番号のチェック
      'telCheck' => array(
        'rule' => '/^\d{10,11}$/',
        'allowEmpty' => false,
        'message' => '電話番号はハイフンなしで入力してください'
      ),

      // メールアドレスのチェック
      'mailCheck' => array(
        'rule' => 'email',
        'allowEmpty' => false,
        'message' => 'メールアドレスを入力してください'
      ),

      // 郵便番号のチェック
      'zipCheck' => array(
        'rule' => '/^\d{3}-\d{4}$/',
        'allowEmpty' => false,
        'message' => '3桁 - 4桁の形式で入力してください'
      ),
    ),
  );

 
上記の「rule」では、
「/^\d{10,11}$/」(10桁~11桁の数値)
「/^\d{3}-\d{4}$/」(3桁の数値 + 「-」 + 4桁の数値)
のように、正規表現を使って入力条件を指定しています。
 
 

2.Controllerに、条件よって使わないバリデーションを削除する処理を記述

 
続いて、1で設定したバリデーションを、条件によって使わない処理を記述していきます。
 
入力された「連絡手段」を「$this->request->data['Contact']['method']」で取得し、電話の場合、メールの場合、電話の場合と振り分け、必要ないバリデーションを「unset」コマンドで削除していきます。
 
その結果、必要なバリデーションだけが残り、その処理が実行される、という仕組みになっています。
 

  public function add()
  {
    if ($this->request->is('post') || $this->request->is('put')) {

      // 電話が選択された場合
      if     ( $this->request->data['Contact']['method'] == "1" ) {
        unset ( $this->Contact->validate["contact_number"]["telCheck"] );
        unset ( $this->Contact->validate["contact_number"]["mailCheck"] );
        unset ( $this->Contact->validate["contact_number"]["zipCheck"] );
      // メールが選択された場合
      } elseif ( $this->request->data['Contact']['method'] == "2" ) {
        unset ( $this->Contact->validate["contact_number"]["telCheck"] );
        unset ( $this->Contact->validate["contact_number"]["mailCheck"] );
        unset ( $this->Contact->validate["contact_number"]["zipCheck"] );
      // 郵送が選択された場合
      } elseif ( $this->request->data['Contact']['method'] == "3" ) {
        unset ( $this->Contact->validate["contact_number"]["telCheck"] );
        unset ( $this->Contact->validate["contact_number"]["mailCheck"] );
        unset ( $this->Contact->validate["contact_number"]["zipCheck"] );
      // その他が選択された場合
      } else {
        unset ( $this->Contact->validate["contact_number"]["telCheck"] );
        unset ( $this->Contact->validate["contact_number"]["mailCheck"] );
        unset ( $this->Contact->validate["contact_number"]["zipCheck"] );
      }

      // エラーがない場合は正常処理
      if ( $this->Contact->validates() ) {
        if ($this->Contact->save($this->request->data)) {
          $this->Session->setFlash(__('The contact has been saved'));
          $this->redirect(array('action' => 'index'));
        } else {
          $this->Session->setFlash(__('The contact could not be saved. Please, try again.'));
        }
      }
    }
    $this->set(compact('contacts'));
  }

 
 
ちなみに、この「unset」は CakePHP 2.2で追加されたため、CakePHP 2系でも 2.2より前のものではこの方法は使えません。
 
 

CakePHPで条件によってバリデーションを振り分ける処理のまとめ

 
入力条件によってバリデーションを振り分ける処理として、今回は「unset」関数を使ってすでにあるバリデーションを削除していく、という処理で条件に合致するバリデーションを指定する方法を紹介しました。
 
これ以外にも方法はあるようですが、この方法は理解しやすく、実装しやすい方法だと感じます。

 - CakePHP 3.x 4.x 5.x

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

CakePHP4、5でSELECT telephone as tel FROM usersの様にasでカラムに別名を付ける方法
CakePHP4、5でSELECT telephone as tel FROM usersの様にasでカラムに別名を付ける方法

CakePHP4、CakePHP5でクリエビルダーを利用してテーブルからレコードを取得する際、asを使用してカラムの別名で値を取得したい場合の対応方法を解説。また、別名にはハイフンやアスタリスクなど使用できない文字がある点も解説。

CakePHP3のcontroller内でテンプレート、レイアウトを変更する際の指定方法

CakePHP3でテンプレートファイルやレイアウトファイルをデフォルトのものから別のものに変更したい場合の指定方法を解説。

CakePHP4で複数の引数(パラメータ)を付与してコマンドを実行する方法
CakePHP4で複数の引数(パラメータ)を付与してコマンドを実行する方法

CakePHP4でコマンドを実行する際に引数(パラメータ)をコマンド内で受け取る処理について解説。複数個の引数にも対応する記述方法も解説。

CakePHP3で値を入力直後にバリデーションする方法解説
CakePHP3で値を入力直後にバリデーションする方法解説

CakePHP3でバリデーションの実行を保存する時から入力情報を受け取るときに変更する処理の解説。CakePHP3ではnewEntity()の処理でバリデートするため1行追加で対応可能。

URL短縮サービス「TTTオンライン(https://ttt.onl)」公開
URL短縮サービス「TTTオンライン(https://ttt.onl)」公開

URL短縮サービス「TTTオンライン(https://ttt.onl)」を公開。メールやSNSでは使いにくい長いURLを短いURLに変換するサービス。QRコードも。Google URL Shortenerが2019年3月にサービス終了。

CakePHP3で生の SQLの実行はConnectionManagerを使う
CakePHP3で生の SQLの実行はConnectionManagerを使う

CakePHP3で生の SQL文を実行する方法を解説。クリエビルダーを使う場合は TableRegistryを利用するが、SQLを実行する場合は ConnectionManagerを使う。プリペアードステートメントの使用方法も解説。

getParam('action')で取得するアクション名は別関数に移動しても不変
getParam('action')で取得するアクション名は別関数に移動しても不変

CakePHP4系、5系では「getParam()」で処理中のアクション名を取得できる。そのアクションから別関数を呼び出してた関数でアクション名を調べたが同一の名称だった。

CakePHP3のユーザ管理・認証プラグイン CakeDC/Usersの導入・機能解説・3.1.5対応
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応

CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。

CakePHP3でcomposerを利用してライブラリ・プラグインをインストールする方法

CakePHP3でcomposerを使ってパッケージ(ライブラリ、プラグイン)をインストールする方法の解説。PHPを使うのはCakePHP3が初めてというような方への使い方から解説。

CakePHPのFlashエラーは出るが入力項目ごとのメッセージが出ないエラーの原因
CakePHPのFlashエラーは出るが入力項目ごとのメッセージが出ないエラーの原因

Bakeして自動生成した入力フォーム処理を元に少し処理を追加したら、入力エラーがあってもエラーメッセージが表示されなくなった。原因はリダイレクトの処理にあった。