Symfonyでファイルアップロード付きフォームを作る方法を完全ガイド!初心者でもわかる実践ステップ
生徒
「Symfonyでフォームを作っているんですが、画像ファイルをアップロードする機能も追加したいんです。どうやって作るんでしょうか?」
先生
「Symfonyのフォームには、ファイル選択用の入力フィールドが用意されています。エンティティと組み合わせれば、画像の保存まで簡単に作れますよ。」
生徒
「実際にどんなコードを書くのか想像がつかなくて…。初心者でも作れますか?」
先生
「もちろんです。ファイルアップロードの仕組みは難しそうに見えますが、流れさえ理解すればとてもシンプルですよ。一緒に基本から見ていきましょう。」
1. Symfonyでファイルアップロードフォームを作る基本の考え方
Symfonyでファイルアップロード機能を作るためには、主に次の3つを理解する必要があります。
- ① FormTypeに FileType を追加すること
- ② コントローラでアップロードファイルを処理すること
- ③ 保存先フォルダへファイルを移動すること
特に「ファイルをどのタイミングで保存するか」が重要で、Symfonyでは $uploadedFile->move() を使って安全に保存できます。
ファイルは危険も伴うため、バリデーションやファイル形式チェックも併せて行うのが一般的です。
2. FormTypeでファイル入力フィールドを定義する
Symfonyのフォームでファイルを扱うには、FileType を使います。これは、HTMLでいう <input type="file">
を生成するフィールドタイプです。
use Symfony\Component\Form\Extension\Core\Type\FileType;
$builder
->add('imageFile', FileType::class, [
'label' => '画像をアップロード',
'mapped' => false,
'required' => false,
]);
特に重要なのは mapped: false です。 なぜなら、アップロードされるファイルは通常エンティティのプロパティではなく、 一度コントローラで処理して、ファイル名だけをエンティティに保存するからです。
3. Twigでファイルアップロードフォームを表示する
Twig側でファイルを扱うには、フォーム開始タグの中に enctype="multipart/form-data" が必ず必要です。
Symfonyでは {{ form_start(form) }} が自動で設定してくれます。
{{ form_start(form) }}
{{ form_row(form.imageFile) }}
<button class="btn btn-primary">送信</button>
{{ form_end(form) }}
form_row を使えばラベル・入力欄・エラー表示を自動でまとめてくれます。 Bootstrap と組み合わせることで、見た目も整ったフォームになります。
4. コントローラでアップロードファイルを処理する方法
ここがアップロード処理の中心です。 UploadedFile クラスを使って、ファイルを安全に保存します。
$imageFile = $form->get('imageFile')->getData();
if ($imageFile) {
$newFilename = uniqid().'.'.$imageFile->guessExtension();
$imageFile->move(
$this->getParameter('upload_directory'),
$newFilename
);
$entity->setImageName($newFilename);
}
このようにして、ファイルはサーバーの指定フォルダに保存され、 データベースには「ファイル名」だけが保存される仕組みになります。
uniqid() を使う理由は、ファイル名の衝突(同じ名前)を避けるためです。 ファイルの上書き事故を防ぐため、実践でもよく使われる方法です。
5. services.yamlでアップロード先を設定する
例えば /public/uploads にファイルを保存したい場合、設定ファイルでパスを指定します。
parameters:
upload_directory: '%kernel.project_dir%/public/uploads'
こうしておくことでコントローラから $this->getParameter('upload_directory') で取得できます。
6. バリデーションで安全にファイルを受け取る
ファイルアップロードは危険も伴うため、安全性を高めるにはバリデーションが必須です。 Symfonyにはファイル専用のバリデーションがあります。
use Symfony\Component\Validator\Constraints\File;
new File([
'maxSize' => '2M',
'mimeTypes' => ['image/jpeg', 'image/png'],
'mimeTypesMessage' => 'JPEG または PNG 画像を選択してください。',
])
不正ファイルや巨大ファイルを避けられるため、現場でもよく使われます。
7. 保存した画像を表示する方法
保存した画像を画面に表示するには、単にアップロードフォルダのパスを Twig に渡すだけです。
<img src="/uploads/{{ entity.imageName }}" alt="アップロード画像">
アップロードした内容をプレビューすると、ユーザーにとって使いやすい画面になります。
8. 全体の流れを初心者向けに整理してみよう
ファイルアップロードはやや複雑に見えるかもしれませんが、実際の流れは次のとおりです。
- ① フォームで FileType を定義する
- ② ユーザーがファイルを選ぶ
- ③ コントローラでファイルを受け取る
- ④ move() メソッドでサーバーに保存する
- ⑤ ファイル名をエンティティに保存する
- ⑥ Twigで画像を表示する
意外とシンプルで、初心者でも一度理解すればすぐ応用できる機能です。 Symfonyが用意している仕組みが整っているため、安全で再利用しやすい実装になります。