はじめに
Webアプリケーションでは、ユーザーからの入力値が正しい形式かどうかを確認する「バリデーション(入力値検証)」が欠かせません。CakePHPには強力なバリデーション機能が組み込まれており、少ないコードで多彩なルールを適用できます。
この記事では、CakePHPのバリデーションの基本的な仕組みから、カスタムルールの作成、エラーメッセージのカスタマイズまでを順番に解説します。
バリデーションの基本構造
CakePHPのバリデーションは、主に Tableクラス の validationDefault() メソッドに記述します。Validatorオブジェクトにルールをチェーンして追加していくスタイルです。
// src/Model/Table/UsersTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function validationDefault(Validator $validator): Validator
{
$validator
->notEmptyString('username', 'ユーザー名は必須です')
->minLength('username', 3, 'ユーザー名は3文字以上で入力してください')
->maxLength('username', 20, 'ユーザー名は20文字以内で入力してください');
$validator
->email('email', false, 'メールアドレスの形式が正しくありません')
->notEmptyString('email', 'メールアドレスは必須です');
$validator
->minLength('password', 8, 'パスワードは8文字以上で入力してください')
->notEmptyString('password', 'パスワードは必須です');
return $validator;
}
}
notEmptyString や email などのメソッドは、CakePHPがあらかじめ用意しているビルトインルールです。引数にはフィールド名、続いてオプション、エラーメッセージを渡すのが基本パターンです。
よく使うビルトインルール
CakePHPにはさまざまなビルトインルールが用意されています。代表的なものを確認しておきましょう。
$validator
// 必須チェック
->requirePresence('title', 'create', 'タイトルフィールドは必須です')
->notEmptyString('title', 'タイトルは空にできません')
// 数値・範囲チェック
->integer('age', '年齢は整数で入力してください')
->range('age', [0, 120], '年齢は0〜120の範囲で入力してください')
// 文字列長チェック
->maxLength('bio', 200, '自己紹介は200文字以内にしてください')
// 正規表現チェック
->regex('phone', '/^\d{10,11}$/', '電話番号は10〜11桁の数字で入力してください')
// URL チェック
->url('website', false, 'URLの形式が正しくありません')
// 日付チェック
->date('birthday', ['ymd'], '日付はYYYY-MM-DD形式で入力してください');
requirePresence はリクエストにそのフィールド自体が存在するかを確認するルールで、第2引数に 'create'(新規作成時のみ)や 'update'(更新時のみ)を渡すことで場面に応じた検証が可能です。
カスタムバリデーションルールの作成
ビルトインルールでは対応できない要件には、独自のバリデーションルールを作成します。add() メソッドにクロージャを渡すのが最もシンプルな方法です。
$validator
->add('username', 'noSpaces', [
'rule' => function ($value, $context) {
// スペースを含む場合はfalseを返す
return strpos($value, ' ') === false;
},
'message' => 'ユーザー名にスペースは使用できません',
])
->add('username', 'reservedWords', [
'rule' => function ($value, $context) {
$reserved = ['admin', 'root', 'system'];
return !in_array(strtolower($value), $reserved, true);
},
'message' => 'そのユーザー名は使用できません',
]);
$context 引数には、現在のエンティティデータや操作の種類(newRecord か否か)などが含まれます。他フィールドの値を参照したい場合に活用できます。
$validator
->add('password_confirm', 'matchPassword', [
'rule' => function ($value, $context) {
// passwordフィールドと一致するか確認
return isset($context['data']['password'])
&& $value === $context['data']['password'];
},
'message' => 'パスワードが一致しません',
]);
複数のバリデーションセットを使い分ける
CakePHPでは、新規作成用・更新用など場面ごとに異なるバリデーションセットを定義できます。
// 更新用のバリデーションセットを追加
public function validationUpdate(Validator $validator): Validator
{
$validator
->notEmptyString('email', 'メールアドレスは必須です')
->email('email', false, 'メールアドレスの形式が正しくありません');
// パスワードは任意(空なら変更しない)
$validator
->allowEmptyString('password')
->minLength('password', 8, 'パスワードは8文字以上で入力してください');
return $validator;
}
コントローラー側では patchEntity() の第3引数でセットを指定します。
// src/Controller/UsersController.php
// 更新時はvalidationUpdateセットを使用
$user = $this->Users->patchEntity(
$user,
$this->request->getData(),
['validate' => 'update']
);
バリデーションエラーの取得と表示
コントローラーでエラーを確認し、Viewに渡すのが一般的な流れです。
// コントローラーでエラー確認
if ($this->Users->save($user)) {
$this->Flash->success('保存しました');
return $this->redirect(['action' => 'index']);
}
// エラーがある場合はそのままViewへ(エラーは$userに紐づく)
$this->Flash->error('入力内容を確認してください');
Bladeのような独自テンプレートではなく、CakePHPのテンプレートでは FormHelper を使うとエラーが自動で表示されます。
// テンプレート(templates/Users/add.php)
echo $this->Form->create($user);
echo $this->Form->control('username', ['label' => 'ユーザー名']);
// バリデーションエラーが自動的にフィールド下に表示される
echo $this->Form->control('email', ['label' => 'メールアドレス']);
echo $this->Form->control('password', ['type' => 'password', 'label' => 'パスワード']);
echo $this->Form->button('登録');
echo $this->Form->end();
FormHelper::control() はエンティティに紐づいたエラー情報を自動的に読み取り、CSSクラスの付与やメッセージ表示を行ってくれます。
まとめ
CakePHPのバリデーション機能のポイントをまとめます。
validationDefault()にルールを記述するのが基本notEmptyStringやemailなどの ビルトインルール が豊富に用意されているadd()にクロージャを渡すことで カスタムルール を自由に定義できる$contextを使うと 他フィールドの値を参照 したルールも書ける- 複数の バリデーションセット を定義して場面ごとに使い分けられる
- FormHelper と組み合わせるとエラー表示が自動化される
バリデーションを適切に実装することで、不正なデータの混入を防ぎ、アプリケーションの安全性と品質を高めることができます。ぜひ実際のプロジェクトで活用してみてください。