Symfonyでカスタムバリデーションルールを作成する方法!初心者にもやさしく解説
生徒
「Symfonyで自分だけの特別なバリデーションルールって作れるんですか?」
先生
「はい、Symfonyでは標準のバリデーションルールに加えて、自作のカスタムバリデーションルールを作成できます。」
生徒
「へえ!じゃあ例えば、郵便番号が「123-4567」みたいな形式じゃないとエラーにしたい時も?」
先生
「まさにそれがカスタムバリデーションの出番です。では一緒に作り方を見ていきましょう!」
1. Symfonyでカスタムバリデーションを作るとは?仕組みを解説
Symfony(シンフォニー)でフォームの入力値をチェックする際、あらかじめ用意されている「必須チェック(NotBlank)」や「メール形式チェック(Email)」といった既存のルールをConstraint(制約)と呼びます。
しかし、実際の開発では「特定の社内ID形式か」「禁止ワードが含まれていないか」など、標準機能だけでは足りないケースが出てきます。そこで役立つのがカスタムバリデーションです。これは、自分たちで独自の「合格ルール」を定義する仕組みのことです。
未経験者向けのイメージ例:
例えば、「果物の名前を入力する欄」があったとします。ここに「野菜」が入力されたらエラーにしたい場合、既存のルールには「果物かどうか」を判定するものはありません。そこで、「入力された文字が、リンゴ・バナナ・ミカンのどれかに一致するか?」というあなた専用の判定機を自作する、これがカスタムバリデーションのイメージです。
カスタムバリデーションを実現するには、役割の異なる以下の2つのファイル(クラス)をセットで作るのが基本ルールです:
- ① ルールの定義書(Constraint):ルールの「名前」や、エラー時に表示する「メッセージ内容」を決めるファイルです。
- ② 実際の判定機(ConstraintValidator):届いた値が「正しいか、間違いか」をプログラムで論理的にチェックする、心臓部となるファイルです。
この2つを連携させることで、Symfonyの強力なバリデーションシステムに、あなた独自のルールを組み込むことができるようになります。
2. どんな場面で使うの?初心者向けにイメージしよう
例えば、会員登録の時に「電話番号が090や080ではじまる10桁の数字でなければならない」といった条件を追加したいとします。これをバリデーションルールとして登録することで、ユーザーが間違った形式の電話番号を入力した場合に「エラーメッセージ」を表示できます。
これは「条件によってエラーにしたい」という要求をプログラムでチェックすることです。
3. Constraintクラスを作成しよう
まずはルールの「名前」と「メッセージ」を定義するクラスを作成します。
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ZipCode extends Constraint
{
public $message = '郵便番号は「123-4567」の形式で入力してください。';
}
このクラスでは、バリデーションエラーが発生したときに表示するメッセージを設定しています。
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. エンティティで使ってみよう
作成したカスタムバリデーションを、実際に使いたい場所(エンティティなど)に指定します。
use App\Validator\ZipCode;
class User
{
/**
* @ZipCode
*/
protected $postalCode;
}
このように、属性の上に @ZipCode と書くだけで、Symfonyが自動的に先ほどのルールを適用してくれます。
6. サービスとして登録する必要がある?
いいえ。Symfony 5.3以降では、アノテーションを使っていれば自動でサービス登録されます。古いバージョンでは、services.yamlに手動で記述が必要な場合もありますが、最新の環境では不要です。
7. よくあるミスやエラー例と対処法
初心者の方がよくハマるポイントは以下のとおりです:
- クラス名とファイル名が一致していない(大文字・小文字)
- Validatorクラスの名前が Constraint名 + Validator になっていない
- バリデータークラスに
validate()メソッドを正しく書いていない - バリデーションを使う対象に
@ZipCodeを忘れている
これらの点を見直すとエラーが解消することが多いです。
8. 他にも作れる!自由なルールでバリデーションしよう
今回紹介した「郵便番号」以外にも、以下のようなカスタムバリデーションが考えられます:
- ニックネームに絵文字を含めない
- パスワードに特定の単語を禁止する
- 生年月日が未来になっていないか
- メールアドレスが会社のドメイン(例:example.co.jp)になっているか
これらも同じように Constraint と ConstraintValidator を使えば簡単に追加できます。