RRelayer
ホーム/機能

バリデーション#

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」。バリデーションは単独で使うより、この型で使うのが基本。

最終更新: 2026-05-19
変更履歴 (2)
  • v0.17.0 の i18n でバリデーション既定メッセージがローカライズされる旨をクロスリンク追記
  • 新規作成