2021.06.30
【PHP応用】入力チェック(バリデーション)
テーブルに登録や更新を行う際、
テーブルで定義した型と違う型を入力し処理を行ってしまうと
PDOExceptionが発生してしまい処理が中断してしまいます。
それを防ぐために入力チェックを行います。
入力された値をチェックすること(妥当性の確認)を
バリデーションといいます。
バリデーションで、不正なデータの入力を防ぐことで、
XSSやSQLインジェクションを防ぐ助けにもなります。
(確実な防御のためにはそれぞれ専用の対策をとります。)
実例
add.ctp(変更)
<h3>Add Form</h3> <?= $this->Form->create($member); /*createの第一引数にエンティティを指定することで、validationDefaultが効くようになる。*/?> Name:<?= $this->Form->text("name"); ?> Age:<?= $this->Form->text("age"); ?> Mail:<?= $this->Form->text("mail"); ?> <?= $this->Form->submit(); ?> <?= $this->Form->end(); ?>
MembersTable.php(変更)
public function validationDefault(Validator $validator) { $validator ->integer('id') ->allowEmpty('id', 'create'); // 空を許可してなければ作る $validator ->scalar('name') ->maxLength('name', 50) // 長さは50 ->requirePresence('name', 'create') // 必須設定(SQLだとNOTNULLにあたる) ->notEmpty('name'); // 空を許可しない $validator ->integer('age') ->nonNegativeInteger('age') // ここを追加、自然数のみ許可する ->allowEmpty('age'); // 空を許可する $validator ->scalar('mail') ->maxLength('mail', 50) // 長さは50 ->allowEmpty('mail'); // 空を許可する return $validator; }
入力チェック
前節で以下の記述を追加してもらいました。
->nonNegativeInteger('age')
このように、デフォルトのルールの他に任意のルールを適用することが可能です。
入力チェックの流れ
値のチェックには2段階あります。
- バリデーション(validation)
- Entity作成・更新時に行われます。形式や必須項目漏れ等のチェックです。
エンティティ構築前に行われ、 validationDefaultメソッドの設定に従います。 - アプリケーションルール(application rule)
- Databaseに作用する(insert, update, delete)際に行われます。データベース上のデータを絡めた)存在チェックや重複チェックです。
エンティティをdatabaseにsaveする前に行われ、
buildRulesメソッドに記述します。(今回は使っていません)
MembersController.php
public function add() { $member = $this->Members->newEntity(); if ($this->request->is('post')) { // エンティティにリクエストされた値を入れる(この際にvalidationが行われる) $member = $this->Members->patchEntity($member, $this->request->getData()); // databaseをsaveする(この際にapplication Ruleが行われる) if ($this->Members->save($member)) { $this->Flash->success(__('The member has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The member could not be saved. Please, try again.')); } $this->set(compact('member')); }
バリデーションルールの種類例
数字
- numeric
- 数字かどうか
- naturalNumber
- 符号なしの数字かどうか
- nonNegativeInteger
- マイナスを許可しない
英数字
- alphanumeric
- 半角英数字かどうか
指定文字数
- minLength
- 指定文字以上であるかどうか
- maxLength
- 指定文字以下であるかどうか
日付
- date
- 日付のフォーマットであるかどうか
メールアドレス
- メールアドレスであるかどうか