Symfonyのフォーム送信後にデータを保存する方法をやさしく解説!初心者でもわかるフォーム処理入門
生徒
「Symfonyでお問い合わせフォームを作ったのですが、送信ボタンを押した後に、そのデータを保存する方法がわかりません。どうやってデータベースに残せばいいですか?」
先生
「Symfonyのフォーム処理では、フォームを表示して、送信されたリクエストを受け取り、問題がなければデータベースに保存する、という流れで考えると理解しやすいですよ。」
生徒
「フォーム送信後の流れが頭の中でうまくイメージできていなくて…。人間の世界の例にたとえてもらえると助かります。」
先生
「では、Symfonyのフォームを紙の申込書にたとえて、送信後にデータを保存する仕組みを、ゆっくり一緒に見ていきましょう。SymfonyのフォームとDoctrine ORMを組み合わせると、自然な流れでデータ保存ができるようになりますよ。」
1. Symfonyのフォーム送信後のイメージをつかもう
まずは、Symfonyのフォーム送信後にデータを保存する流れを、やさしいイメージからつかみましょう。Symfonyのフォームは、Web画面に表示される入力欄だと考えるとわかりやすいです。ユーザーが名前やメールアドレスを入力して送信すると、その情報は「リクエスト」と呼ばれる荷物のような形でサーバーに届きます。
紙の世界で考えると、「紙の申込書(フォーム)」に必要な情報を書いて、「受付窓口(サーバー)」に渡すイメージです。受付の人は、内容をチェックして問題がなければ、「台帳(データベース)」にきちんと記録します。Symfonyでフォーム送信後にデータを保存する方法も、これと同じ流れです。
Symfonyのフォーム処理では、次のようなステップで動きます。
- フォームを表示する(入力欄を画面に出す)
- ユーザーがフォームに入力して送信する
- 送信されたデータをコントローラで受け取る
- フォームの内容が正しいかチェックする
- 問題がなければDoctrine ORMを使ってデータベースに保存する
この記事では、この中でも特に「フォーム送信後にデータを保存する方法」に焦点を当てて、初心者向けに丁寧に説明していきます。Symfony初心者や、プログラミング経験がない人でも読めるように、「Symfony フォーム データ保存」「Symfony フォーム送信 後処理」「Symfony Doctrine 保存」といったキーワードも交えながら、フォーム処理の全体像をつかんでいきましょう。
2. フォーム送信後の処理はコントローラが担当する
Symfonyでは、フォームから送信されたデータは、まず「コントローラ」と呼ばれる場所で受け取ります。コントローラは、Symfonyアプリケーションの中で「受付係」のような役割を持っています。ユーザーからのリクエストを受け取り、何をするか判断して、テンプレートやデータベースに橋渡しをします。
フォーム送信後にデータを保存する処理も、このコントローラの中に書きます。Symfonyのフォーム処理では、一般的に次のような流れで書かれます。
- フォームオブジェクトを作成する
- リクエストをフォームに渡して、送信されたかどうかを調べる
- バリデーション(入力チェック)を通過したら、エンティティに値をセットして保存する
実際のプログラムでは、コントローラのメソッドの中で、フォームとリクエストを結びつける処理を書きます。たとえば、お問い合わせフォームで名前とメールアドレスを保存したい場合、Symfonyのコントローラの中でフォームオブジェクトを作成し、送信されたときだけデータベースに保存するように書きます。
ここで大切なのは、「フォームを表示する処理」と「フォーム送信後に保存する処理」が、同じアクションメソッドの中にセットで書かれることが多い、という点です。Symfony フォーム処理の基本として、「表示も保存も同じコントローラで扱う」という考え方を覚えておくと、後でコードを見たときにも流れを追いやすくなります。
3. handleRequestとisSubmitted・isValidの役割を理解しよう
Symfonyのフォーム送信後にデータを保存する方法を理解するためには、コントローラの中でよく使われるメソッドであるhandleRequest、isSubmitted、isValidの役割を押さえておくことが重要です。これらは、フォーム送信後の流れをコントロールするためのキーワードです。
handleRequestは、「今届いているリクエストの内容をフォームに反映させる」処理を行います。紙の世界で言えば、「受付係が、渡された申込書を手に取って中身を読む」イメージです。これを呼び出すことで、フォームが送信済みかどうかを判断できるようになります。
isSubmittedは、「フォームが送信されたかどうか」を調べるためのメソッドです。まだ画面を開いただけで何も送信していない場合は、ここが「送信されていません」という状態になります。一方、送信ボタンを押したあとは「送信されました」という状態になります。
isValidは、「フォームの内容がルールに従って正しいかどうか」をチェックします。名前が必須なのに空になっている、メールアドレスの形式が間違っている、などのルールに引っかかると、isValidは「正しくない」という結果を返します。逆に、すべてのルールを満たしていれば「正しい」と判定されます。
Symfonyのフォーム送信後にデータを保存するタイミングは、一般的に「フォームが送信されている」かつ「内容が正しい」と判定されたときです。つまり、次のような条件がそろったときに、Doctrine ORMを使ってデータベースに保存する処理を実行します。
- フォームが送信されている(
isSubmitted()が真) - フォームの内容が正しい(
isValid()が真)
4. Symfonyフォーム送信後にDoctrineでデータベースへ保存する基本パターン
ここからは、Symfonyのフォーム送信後にデータを保存する基本パターンを具体的に見ていきます。Symfonyでは、データベースとのやり取りにDoctrine ORMを使うことが多いです。Doctrine ORMは、テーブルの行を「エンティティ」と呼ばれるオブジェクトとして扱う仕組みです。
例えば、「お問い合わせ」というテーブルに、名前やメールアドレス、メッセージを保存したい場合は、Contactのようなエンティティクラスを作成します。そして、フォーム送信後にこのエンティティに値を入れて、Doctrineのエンティティマネージャに保存を依頼します。
Symfonyフォーム送信後の保存処理の流れは、次のようになります。
- エンティティ(たとえば
Contact)のインスタンスを作る - フォームを作成し、エンティティと結びつける
handleRequestでリクエスト内容をフォームに反映させる- 送信されていて、内容が正しいときだけ保存処理を行う
persistとflushでデータベースに書き込む
実際のSymfonyコントローラのイメージは次のようになります。
public function contact(Request $request, EntityManagerInterface $em): Response
{
$contact = new Contact();
$form = $this->createForm(ContactType::class, $contact);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($contact);
$em->flush();
return $this->redirectToRoute('contact_thanks');
}
return $this->render('contact/form.html.twig', [
'form' => $form->createView(),
]);
}
このコードでは、Symfonyのフォーム送信後にデータを保存する方法の代表的な書き方を示しています。persistは「このエンティティを保存対象として登録する」という意味で、flushは「登録されている内容を実際にデータベースへ流し込む」というイメージです。
紙の世界でたとえると、persistは「台帳に書き写す準備をする」、flushは「実際に台帳にペンで記入する」動きに近いです。Symfony フォームとDoctrineの組み合わせを理解しておくと、「Symfony フォーム データ保存」「Symfony フォーム Doctrine 連携」といったキーワードで検索したときにも、自分のコードの意味がよくわかるようになります。
5. フォーム送信後に画面を切り替えて「保存できた」を伝える
フォーム送信後にデータを保存したあとは、ユーザーに「保存できました」とわかる画面を見せてあげることが多いです。Symfonyでは、データ保存が終わったあとに別のルートへリダイレクトすることで、サンクスページや完了画面を表示します。
先ほどの例では、$this->redirectToRoute('contact_thanks')というコードで、contact_thanksという名前のルートに移動しています。これにより、ユーザーは同じフォーム画面にとどまるのではなく、「お問い合わせありがとうございました」というページに進みます。
このリダイレクトのしくみは、「同じ申込書を二重で送信してしまう」ことを防ぐ意味もあります。一度保存したデータを、もう一度同じリクエストで保存してしまうのを避けるために、Symfonyのフォーム処理では、送信後に別ページへ移動するパターンがよく使われます。
Twigテンプレート側では、たとえば次のようにシンプルな完了メッセージを表示できます。
<h1>お問い合わせを受け付けました</h1>
<p>このたびはご連絡ありがとうございます。送信いただいた内容は、Symfonyアプリケーションのデータベースに保存されました。</p>
このように、Symfony フォーム送信後の流れとして、「データ保存」だけでなく「ユーザーに完了を伝える画面」までセットで考えておくと、実際のWebアプリケーションらしい動きになります。
6. Symfonyフォーム送信後のデータ保存でつまずきやすいポイント
最後に、Symfonyのフォーム送信後にデータを保存しようとしたときに、初心者がつまずきやすいポイントと、その考え方を整理しておきます。Symfony フォーム処理やDoctrine ORMに慣れていないと、「なぜか保存されない」「エラーは出ていないのにテーブルが空のまま」といった状況になりがちです。
6-1. isSubmittedとisValidの条件を書いていない
よくある原因のひとつは、フォーム送信後のデータ保存処理を、isSubmittedやisValidの条件で囲んでいないことです。フォームがまだ送信されていない状態で保存処理を書いてしまうと、意図しないタイミングで動いてしまったり、フォームとエンティティの内容が正しく結びつかないまま保存されてしまう可能性があります。
Symfonyのフォーム送信後にデータを保存する基本形として、「送信されていて、かつ有効かどうか」を必ず条件に入れる、というパターンを覚えておきましょう。
6-2. flushを呼び忘れている
Doctrine ORMでデータを保存するときに、persistだけを書いてflushを呼び忘れていると、データベースには何も書き込まれません。準備だけして実際には書き込んでいない状態なので、「保存されたつもりで実は保存されていない」という状態になります。
Symfony フォームとDoctrineを使うときは、「persistしてからflushする」という二段階の動きをセットで書くクセをつけておくと安心です。これにより、「Symfony フォーム データ保存 されない」というトラブルを減らすことができます。
6-3. エンティティとフォームタイプの紐づけが合っていない
もうひとつのつまずきポイントは、エンティティとフォームタイプの設定が合っていないケースです。たとえば、エンティティ側のプロパティ名とフォーム側のフィールド名がずれていたり、フォームタイプで指定しているクラスが違っていたりすると、Symfonyのフォーム送信後にエンティティへデータが正しく入らなくなります。
フォームとエンティティは、「どの入力欄がどのプロパティに対応しているか」を一致させることが大切です。Symfony フォームの公式ドキュメントや、自分のプロジェクトのエンティティ定義を見比べながら、「名前」「メールアドレス」「メッセージ」といった項目がきちんと対応しているかを確認してみてください。
このように、Symfony フォーム送信後にデータを保存する方法は、一見むずかしそうに見えても、紙の申込書と受付の流れにたとえて考えると理解しやすくなります。フォーム表示、送信、バリデーション、Doctrineでの保存という流れを意識しながら、自分のSymfonyアプリケーションで少しずつ試してみましょう。