カテゴリ: Symfony 更新日: 2026/02/25

Symfonyでカスタムバリデーションルールを作成する方法!初心者にもやさしく解説

Symfonyでカスタムバリデーションルールを作成する方法
Symfonyでカスタムバリデーションルールを作成する方法

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

生徒

「Symfonyで自分だけの特別なバリデーションルールって作れるんですか?」

先生

「はい、Symfonyでは標準のバリデーションルールに加えて、自作のカスタムバリデーションルールを作成できます。」

生徒

「へえ!じゃあ例えば、郵便番号が「123-4567」みたいな形式じゃないとエラーにしたい時も?」

先生

「まさにそれがカスタムバリデーションの出番です。では一緒に作り方を見ていきましょう!」

1. Symfonyでカスタムバリデーションを作るとは?仕組みを解説

1. Symfonyでカスタムバリデーションを作るとは?仕組みを解説
1. Symfonyでカスタムバリデーションを作るとは?仕組みを解説

Symfony(シンフォニー)でフォームの入力値をチェックする際、あらかじめ用意されている「必須チェック(NotBlank)」や「メール形式チェック(Email)」といった既存のルールをConstraint(制約)と呼びます。

しかし、実際の開発では「特定の社内ID形式か」「禁止ワードが含まれていないか」など、標準機能だけでは足りないケースが出てきます。そこで役立つのがカスタムバリデーションです。これは、自分たちで独自の「合格ルール」を定義する仕組みのことです。

未経験者向けのイメージ例:

例えば、「果物の名前を入力する欄」があったとします。ここに「野菜」が入力されたらエラーにしたい場合、既存のルールには「果物かどうか」を判定するものはありません。そこで、「入力された文字が、リンゴ・バナナ・ミカンのどれかに一致するか?」というあなた専用の判定機を自作する、これがカスタムバリデーションのイメージです。

カスタムバリデーションを実現するには、役割の異なる以下の2つのファイル(クラス)をセットで作るのが基本ルールです:

  • ① ルールの定義書(Constraint):ルールの「名前」や、エラー時に表示する「メッセージ内容」を決めるファイルです。
  • ② 実際の判定機(ConstraintValidator):届いた値が「正しいか、間違いか」をプログラムで論理的にチェックする、心臓部となるファイルです。

この2つを連携させることで、Symfonyの強力なバリデーションシステムに、あなた独自のルールを組み込むことができるようになります。

2. どんな場面で使うの?初心者向けにイメージしよう

2. どんな場面で使うの?初心者向けにイメージしよう
2. どんな場面で使うの?初心者向けにイメージしよう

例えば、会員登録の時に「電話番号が090や080ではじまる10桁の数字でなければならない」といった条件を追加したいとします。これをバリデーションルールとして登録することで、ユーザーが間違った形式の電話番号を入力した場合に「エラーメッセージ」を表示できます。

これは「条件によってエラーにしたい」という要求をプログラムでチェックすることです。

3. Constraintクラスを作成しよう

3. Constraintクラスを作成しよう
3. Constraintクラスを作成しよう

まずはルールの「名前」と「メッセージ」を定義するクラスを作成します。


namespace App\Validator;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class ZipCode extends Constraint
{
    public $message = '郵便番号は「123-4567」の形式で入力してください。';
}

このクラスでは、バリデーションエラーが発生したときに表示するメッセージを設定しています。

4. ConstraintValidatorを作成しよう

4. ConstraintValidatorを作成しよう
4. ConstraintValidatorを作成しよう

続いて、実際に条件に合っているかどうかを「判断」するクラスを作ります。ここが本体です。


namespace App\Validator;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ZipCodeValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!preg_match('/^\d{3}-\d{4}$/', $value)) {
            $this->context->buildViolation($constraint->message)
                ->addViolation();
        }
    }
}

このコードでは、郵便番号が「123-4567」のような形式かどうかを preg_match で確認しています。正しくなければエラーメッセージを出します。

5. エンティティで使ってみよう

5. エンティティで使ってみよう
5. エンティティで使ってみよう

作成したカスタムバリデーションを、実際に使いたい場所(エンティティなど)に指定します。


use App\Validator\ZipCode;

class User
{
    /**
     * @ZipCode
     */
    protected $postalCode;
}

このように、属性の上に @ZipCode と書くだけで、Symfonyが自動的に先ほどのルールを適用してくれます。

6. サービスとして登録する必要がある?

6. サービスとして登録する必要がある?
6. サービスとして登録する必要がある?

いいえ。Symfony 5.3以降では、アノテーションを使っていれば自動でサービス登録されます。古いバージョンでは、services.yamlに手動で記述が必要な場合もありますが、最新の環境では不要です。

7. よくあるミスやエラー例と対処法

7. よくあるミスやエラー例と対処法
7. よくあるミスやエラー例と対処法

初心者の方がよくハマるポイントは以下のとおりです:

  • クラス名とファイル名が一致していない(大文字・小文字)
  • Validatorクラスの名前が Constraint名 + Validator になっていない
  • バリデータークラスに validate() メソッドを正しく書いていない
  • バリデーションを使う対象に @ZipCode を忘れている

これらの点を見直すとエラーが解消することが多いです。

8. 他にも作れる!自由なルールでバリデーションしよう

8. 他にも作れる!自由なルールでバリデーションしよう
8. 他にも作れる!自由なルールでバリデーションしよう

今回紹介した「郵便番号」以外にも、以下のようなカスタムバリデーションが考えられます:

  • ニックネームに絵文字を含めない
  • パスワードに特定の単語を禁止する
  • 生年月日が未来になっていないか
  • メールアドレスが会社のドメイン(例:example.co.jp)になっているか

これらも同じように ConstraintConstraintValidator を使えば簡単に追加できます。

関連記事:
カテゴリの一覧へ
新着記事
New1
CodeIgniter
CodeIgniterでRESTful API開発!初心者でもわかる全体構成ガイド
New2
Symfony
Symfonyのコントローラとは?作成・構造・役割を初心者向けにやさしく解説!
New3
Symfony
Symfonyでバリデーションメッセージを多言語対応する方法!初心者でもわかる国際化の基本
New4
Symfony
Symfonyのキャッシュ機構の基本を理解しよう(HTTPとアプリ別)
人気記事
No.1
Java&Spring記事人気No1
Laravel
Laravelのシングルアクションコントローラとは?使い方と利点
No.2
Java&Spring記事人気No2
Laravel
Laravelで動的パラメータをルートに渡す方法!初心者にもやさしいルートパラメータの使い方入門
No.3
Java&Spring記事人気No3
Laravel
LaravelのBlade構文まとめ!@if @foreach など基本ディレクティブ解説
No.4
Java&Spring記事人気No4
Laravel
Laravelでキャッシュを使う方法(ファイル・Redis・Memcached)
No.5
Java&Spring記事人気No5
Laravel
Laravelで名前付きルートを設定する方法!初心者でもわかるroute()関数の使い方
No.6
Java&Spring記事人気No6
Symfony
Symfonyの依存性注入(DI)とは?コンストラクタでの注入方法を初心者向けに徹底解説
No.7
Java&Spring記事人気No7
Laravel
Laravelのマイグレーション履歴を確認する方法を徹底解説!migrate:statusの使い方
No.8
Java&Spring記事人気No8
Laravel
Laravelのルート一覧を確認する方法!初心者でもわかるphp artisan route:listの使い方