カテゴリ: Symfony 更新日: 2025/11/23

Symfonyで複数フィールドを同時にバリデーションする方法を徹底解説!初心者にもやさしく解説

Symfonyで複数フィールドに対して同時にバリデーションを行う方法
Symfonyで複数フィールドに対して同時にバリデーションを行う方法

先生と生徒の会話形式で理解しよう

生徒

「Symfonyでフォームを作ったときに、複数の入力項目の関係をチェックすることってできますか?」

先生

「はい、Symfonyのバリデーションには、複数フィールドを同時にチェックする方法も用意されています。」

生徒

「例えば、パスワードと確認用パスワードが一致しているか確認したいんです!」

先生

「その場合は、クラスレベルのバリデーションという方法を使います。仕組みや書き方を一緒に学びましょう!」

1. Symfonyで複数フィールドをチェックしたいとき

1. Symfonyで複数フィールドをチェックしたいとき
1. Symfonyで複数フィールドをチェックしたいとき

通常のSymfonyのバリデーションは、1つのフィールド(項目)に対してルールを設定します。たとえば「名前は必須」や「メールアドレスの形式が正しいか」などです。

しかし、時には複数の項目の関係をチェックしたいことがあります。よくある例は以下のようなケースです。

  • パスワードと確認用パスワードが一致しているか
  • 開始日と終了日の順番が正しいか
  • 「はい」と答えたら、別の項目も必須にする

このようなチェックをしたいときは、「クラス全体に対してバリデーションをかける」というアプローチを使います。

2. クラスレベルバリデーションとは?

2. クラスレベルバリデーションとは?
2. クラスレベルバリデーションとは?

クラスレベルバリデーションとは、1つのフィールドだけでなく、エンティティ全体を見てルールを定義する方法です。

Symfonyでは、@Assert\Callbackという特殊なアノテーションを使うことで、独自のバリデーションメソッドを定義することができます。

そのメソッド内で、必要な複数のフィールドの値を比較し、ルールに違反しているかどうかを判断します。

3. 実際に書いてみよう!パスワード一致チェック

3. 実際に書いてみよう!パスワード一致チェック
3. 実際に書いてみよう!パスワード一致チェック

ここでは「パスワード」と「パスワード確認」の2つのフィールドが一致しているかをチェックする実例を紹介します。


use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Constraints\Callback;

class UserRegistration
{
    /**
     * @Assert\NotBlank()
     */
    private $password;

    /**
     * @Assert\NotBlank()
     */
    private $confirmPassword;

    /**
     * @Assert\Callback
     */
    public function validatePasswords(ExecutionContextInterface $context): void
    {
        if ($this->password !== $this->confirmPassword) {
            $context->buildViolation('パスワードが一致しません。')
                ->atPath('confirmPassword')
                ->addViolation();
        }
    }
}

このコードでは、validatePasswords()というメソッドを作成し、@Assert\Callbackで呼び出しています。

2つのパスワードが一致しない場合にだけ、Symfonyが自動的にエラーを表示してくれます。

4. atPath()とは?エラーの場所を指定する

4. atPath()とは?エラーの場所を指定する
4. atPath()とは?エラーの場所を指定する

atPath()は、「どのフィールドにエラーメッセージを表示するか」を指定するメソッドです。

先ほどの例では、確認用パスワード(confirmPassword)にだけエラーメッセージを表示させたいので、->atPath('confirmPassword')と指定しています。

この指定をしないと、エラーがクラス全体に紐づいてしまい、ユーザーが混乱してしまう可能性があります。

5. Twigテンプレートでエラーを表示する

5. Twigテンプレートでエラーを表示する
5. Twigテンプレートでエラーを表示する

Symfonyでは、フォームのテンプレートで{{ form_row() }}を使えば、自動でエラーメッセージを表示してくれます。

以下のように書くことで、確認用パスワードにエラーがあればその場に表示されます。


{{ form_start(form) }}
    {{ form_row(form.password) }}
    {{ form_row(form.confirmPassword) }}
    <button type="submit">登録</button>
{{ form_end(form) }}

6. 開始日と終了日の順番チェックも可能

6. 開始日と終了日の順番チェックも可能
6. 開始日と終了日の順番チェックも可能

他のよくあるパターンとして、「開始日が終了日より後だったらエラー」というチェックもできます。

以下はその一例です。


/**
 * @Assert\Callback
 */
public function validateDates(ExecutionContextInterface $context): void
{
    if ($this->startDate > $this->endDate) {
        $context->buildViolation('開始日は終了日より前にしてください。')
            ->atPath('startDate')
            ->addViolation();
    }
}

このように、クラスの中で複数のプロパティを比較して、自由にバリデーションを設計できるのがSymfonyの強みです。

7. クラスレベルのバリデーションで注意すべきこと

7. クラスレベルのバリデーションで注意すべきこと
7. クラスレベルのバリデーションで注意すべきこと

以下のポイントに気をつけると、スムーズに複数フィールドのバリデーションができます。

  • @Assert\Callbackのメソッド名は自由に決めてOK
  • バリデーションメソッドには必ずExecutionContextInterfaceを引数に入れる
  • use文を忘れるとエラーになるので注意

また、バリデーションの対象クラスがコントローラで使われているか、フォームと連携しているかも確認しておきましょう。

関連記事:
カテゴリの一覧へ
新着記事
New1
Laravel
Laravelの認証状態をチェックする方法を完全解説!authとAuth::check()を初心者向けにやさしく説明
New2
CodeIgniter
CodeIgniterのコントローラクラスの作り方を完全ガイド!初心者でもわかる基礎から実践まで
New3
Symfony
Symfonyのフォームラベルを多言語対応!初心者でもわかる翻訳設定ガイド
New4
Laravel
Laravelでユーザー登録機能を作る方法!初心者向けにバリデーションとリダイレクトをやさしく解説
人気記事
No.1
Java&Spring記事人気No1
Laravel
Laravelのデータベース設定方法を完全ガイド!初心者でもわかる.envファイルの使い方
No.2
Java&Spring記事人気No2
Laravel
Laravelのビューとは?Bladeテンプレートの基本を解説
No.3
Java&Spring記事人気No3
Laravel
Laravelでセッションを扱う方法!保存方法と利用例を解説
No.4
Java&Spring記事人気No4
Laravel
Laravelのルート一覧を確認する方法!初心者でもわかるphp artisan route:listの使い方
No.5
Java&Spring記事人気No5
Laravel
Laravelでルーティングを設定する方法!web.phpと基本ルートの書き方を初心者向けに徹底解説
No.6
Java&Spring記事人気No6
Laravel
Laravelでログを出力する方法(Monolog・storage/logs)
No.7
Java&Spring記事人気No7
Laravel
LaravelでルートをBladeテンプレートに記述する方法(route関数)
No.8
Java&Spring記事人気No8
Laravel
Laravelのルートキャッシュ機能を活用してパフォーマンス改善!初心者でもわかる完全ガイド