カテゴリ: Symfony 更新日: 2025/12/04

Symfonyのコレクションフォームをバリデーションする方法を完全ガイド!初心者でもわかる入力チェックの基本

Symfonyのコレクションフォームのバリデーション方法
Symfonyのコレクションフォームのバリデーション方法

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

生徒

「Symfonyで、複数のフォームをまとめて扱う方法ってありますか?」

先生

「ありますよ。それが『コレクションフォーム』という機能です。複数の入力欄をひとつにまとめて管理できます。」

生徒

「でも、その場合ってバリデーション(入力チェック)はどうすればいいんですか?」

先生

「いいところに気づきましたね。コレクションフォームでも、しっかりとバリデーションができますよ。やり方を詳しく見ていきましょう!」

1. Symfonyのコレクションフォームとは?

1. Symfonyのコレクションフォームとは?
1. Symfonyのコレクションフォームとは?

コレクションフォームとは、Symfonyで使えるフォーム機能のひとつで、同じ種類の入力フィールドを「複数まとめて」扱える便利な仕組みです。

たとえば、「1人のユーザーが複数の電話番号を持っている」というようなケースで、電話番号入力欄をいくつも表示したいときに使います。

このように、「配列のように繰り返しの入力をまとめて扱う」ときに、CollectionType(コレクションタイプ)を使います。

2. コレクションフォームにバリデーションをかけるとは?

2. コレクションフォームにバリデーションをかけるとは?
2. コレクションフォームにバリデーションをかけるとは?

「バリデーション」とは、フォームに入力された内容が正しいかどうかをチェックする仕組みです。たとえば、空欄禁止や、文字数の制限などがあります。

コレクションフォームでは、1つ1つの「子要素」に対して、それぞれバリデーションを適用します。たとえば、「各電話番号は10桁以上でなければいけない」といった制限をつけることができます。

3. エンティティとバリデーションアノテーションの準備

3. エンティティとバリデーションアノテーションの準備
3. エンティティとバリデーションアノテーションの準備

まずは、バリデーションを使うために、@Assertというアノテーションを使ってルールを指定しておきます。エンティティというのは、データの型や構造を表すPHPクラスのことです。


namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class PhoneNumber
{
    #[Assert\NotBlank(message: "電話番号を入力してください。")]
    #[Assert\Length(min: 10, minMessage: "電話番号は10桁以上で入力してください。")]
    private string $number;

    public function getNumber(): string
    {
        return $this->number;
    }

    public function setNumber(string $number): void
    {
        $this->number = $number;
    }
}

4. コレクションフォームのFormTypeクラスを作成

4. コレクションフォームのFormTypeクラスを作成
4. コレクションフォームのFormTypeクラスを作成

Symfonyでは、フォームの構成をFormTypeというクラスで定義します。今回は、電話番号を複数入力できるフォームを作ります。


namespace App\Form;

use App\Entity\PhoneNumber;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PhoneNumberType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('number', TextType::class);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => PhoneNumber::class,
        ]);
    }
}

5. 親フォームにCollectionTypeを設定する

5. 親フォームにCollectionTypeを設定する
5. 親フォームにCollectionTypeを設定する

次に、コレクションフォームの親となるフォームを作ります。ここで、CollectionTypeを使って、PhoneNumberTypeを繰り返し入力できるようにします。


namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\User;
use App\Form\PhoneNumberType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('phoneNumbers', CollectionType::class, [
            'entry_type' => PhoneNumberType::class,
            'allow_add' => true,
            'by_reference' => false,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

6. コントローラでフォームとバリデーションを連携させる

6. コントローラでフォームとバリデーションを連携させる
6. コントローラでフォームとバリデーションを連携させる

最後に、フォームとエンティティを結びつけて、バリデーションを有効にする処理をコントローラに書きます。


namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\User;
use App\Form\UserType;

class UserController extends AbstractController
{
    #[Route('/user', name: 'user_form')]
    public function form(Request $request): Response
    {
        $user = new User();

        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // データの保存処理など
            return new Response('保存しました!');
        }

        return $this->render('user/form.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

7. バリデーションエラーの表示も自動で行われる

7. バリデーションエラーの表示も自動で行われる
7. バリデーションエラーの表示も自動で行われる

Symfonyのフォームでは、Twigテンプレート側でフォームを正しくレンダリングすれば、バリデーションエラーも自動で表示されます。たとえば以下のように書くことで、エラーメッセージが表示されます。


{{ form_start(form) }}
    {{ form_row(form.phoneNumbers) }}
    <button type="submit">送信</button>
{{ form_end(form) }}

8. バリデーション対象が配列でも安心

8. バリデーション対象が配列でも安心
8. バリデーション対象が配列でも安心

通常のバリデーションと違って、コレクションフォームでは「それぞれの項目に対して同じバリデーションルールを適用する」ことが重要です。Symfonyはこれを標準でサポートしているので、開発者は安心して入力チェックを任せることができます。

しかも、Twigテンプレートでの表示も、ひとつずつ丁寧に繰り返して出力してくれるので、デザイン面でも柔軟に対応できます。

関連記事:
カテゴリの一覧へ
新着記事
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でルートをBladeテンプレートに記述する方法(route関数)
No.7
Java&Spring記事人気No7
Laravel
Laravelのルートキャッシュ機能を活用してパフォーマンス改善!初心者でもわかる完全ガイド
No.8
Java&Spring記事人気No8
Laravel
Laravelでログを出力する方法(Monolog・storage/logs)