バリデーション#
Zod に着想を得たスキーマバリデータで、フィールド別エラーを返します。実用上はほぼ常に フォーム送信=サーバーアクション の中で使うので、まず単体 API を押さえ、その後に関数スタイルページでの実践フロー(送信→検証→失敗なら再描画/成功なら PRG)を示します。
スキーマ宣言#
use Polidog\Relayer\Validation\Validator;
$schema = Validator::object([
'email' => Validator::string()->trim()->email(),
'name' => Validator::string()->trim()->min(1, '名前は必須です。'),
'age' => Validator::int()->min(0)->optional(),
]);利用できる型#
string() / int() / float() / bool() / enum() / object() / array()、および email() / url() などの制約。
string()->trim()->min(1) のようにメソッドチェーンで制約を積み、 optional() で任意フィールドにします。各エラーメッセージは制約メソッドの第 2 引数で上書きできます。
パース(safeParse / ParseResult)#
safeParse() は例外を投げず ParseResult を返します。
$result = $schema->safeParse($input);
if ($result->success) {
$data = $result->data; // 検証済み・型付きデータ
} else {
$errors = $result->errors; // ['email' => 'メッセージ', ...]
}入力($input)はスーパーグローバルではなく、サーバーアクションが渡す $form 配列、または Request から取った値を渡します(規約: ページ/ハンドラで $_POST を直接読まない)。
関数スタイルページでの実践フロー#
バリデーションの典型は「フォーム送信 → 検証 → 失敗ならエラー付きで同じページを再描画 / 成功なら PRG リダイレクト」です。関数スタイルページのファクトリはリクエスト毎に走るので、$errors を参照キャプチャしてハンドラと描画クロージャで共有できます(サーバーアクション / 関数スタイルページ も参照)。
use Polidog\Relayer\Validation\Validator;
use Polidog\Relayer\Router\Component\PageContext;
return function (PageContext $ctx): Closure {
$errors = [];
$old = ['name' => '', 'email' => ''];
$save = $ctx->action('save', function (array $form) use ($ctx, &$errors, &$old) {
$old = $form;
$result = Validator::object([
'name' => Validator::string()->trim()->min(1, '名前は必須です。'),
'email' => Validator::string()->trim()->email('メール形式が不正です。'),
])->safeParse($form);
if (!$result->success) {
$errors = $result->errors; // 描画クロージャで表示。再描画される
return;
}
// $result->data を保存して Post/Redirect/Get
$ctx->redirect('/thanks');
});
return fn () => (
<form action={$save} method="post">
<label>
名前
<input name="name" value={$old['name'] ?? ''} />
</label>
{isset($errors['name'])
? (<p className="error">{$errors['name']}</p>)
: null}
<label>
メール
<input name="email" value={$old['email'] ?? ''} />
</label>
{isset($errors['email'])
? (<p className="error">{$errors['email']}</p>)
: null}
<button>送信</button>
</form>
);
};ポイント:
- CSRF はサーバーアクションが自動付与(サーバーアクション)。
- ハンドラは
render()の前に走るので、return;すればそのまま
$errors 入りでフォームが再描画される。成功時のみ $ctx->redirect() で PRG。
- エラーメッセージは usePHP が自動エスケープして描画(usePHP)。
- 制約メソッドの既定メッセージは
relayer.*カタログでローカライズされ、
リクエストの解決ロケールに追従します(多言語化)。 refine() / required('…') に渡した独自メッセージはそのまま透過。
- クラススタイルなら
#[Auth]同様、PageComponent::action()で同じ流れ。
まとめ#
- 単体:
Validator::object([...])->safeParse($input)→ParseResult
(success / data / errors)。
- 実践: 関数スタイルページ+サーバーアクションで「失敗→再描画 /
成功→PRG」。バリデーションは単独で使うより、この型で使うのが基本。
変更履歴 (2)
- v0.17.0 の i18n でバリデーション既定メッセージがローカライズされる旨をクロスリンク追記
- 新規作成