Symfonyで画像やファイルをアップロードする時のバリデーション完全ガイド!初心者でもわかる入力チェックの基本
生徒
「Symfonyで画像をアップロードするフォームを作ったんですが、サイズや種類を制限するにはどうすればいいですか?」
先生
「それにはバリデーションを使いますよ。画像やファイルのアップロード時に、条件を満たしているかチェックする方法があります。」
生徒
「アップロードできるのは画像だけにしたいんですけど、それもできますか?」
先生
「もちろんできます!ファイルの種類やサイズ、空欄チェックまでしっかり制限できますよ。それでは、具体的なやり方を見ていきましょう。」
1. Symfonyでファイルアップロードを制限する理由
Symfonyでは、画像やファイルをフォームからアップロードできますが、何も制限をかけないと、危険なファイルが送られてしまうこともあります。そこで、ファイルの種類やサイズ、空欄などをバリデーション(入力チェック)して、安全にデータを受け取るようにします。
たとえば、画像以外のファイルを弾いたり、10MBを超える大きなファイルを拒否したりできます。こうした機能は、フォームの設計と一緒に作り込むことができます。
2. SymfonyのValidatorとは?
Symfonyには「バリデーション」と呼ばれる機能があり、データが正しいかどうかを自動でチェックできます。ファイルや画像のチェックも、@Assert\Fileや@Assert\Imageという「アノテーション」で指定します。
アノテーションとは、PHPのコメントのような見た目をしていて、クラスや変数に「こうしてね」というルールを伝える仕組みです。
3. 画像アップロード用エンティティの作成
まずは、画像を保存するためのPhotoというエンティティクラスを作成し、画像ファイルのバリデーションを設定します。
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Photo
{
#[Assert\NotNull(message: "画像ファイルを選択してください。")]
#[Assert\Image(
maxSize: "5M",
mimeTypes: ["image/jpeg", "image/png"],
mimeTypesMessage: "JPEGまたはPNG形式の画像をアップロードしてください。",
maxSizeMessage: "画像サイズは5MB以下にしてください。"
)]
private $imageFile;
public function getImageFile()
{
return $this->imageFile;
}
public function setImageFile($imageFile): void
{
$this->imageFile = $imageFile;
}
}
4. アップロード用のフォームクラスを作る
次に、画像アップロード用のフォームを作ります。FileTypeを使って、ファイル選択欄を表示します。
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\Photo;
class PhotoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('imageFile', FileType::class, [
'label' => '画像ファイル(JPEG/PNG)',
'required' => true,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Photo::class,
]);
}
}
5. コントローラでフォームを処理する
次に、作成したフォームを画面に表示し、アップロードされた画像を受け取る処理をコントローラに記述します。
namespace App\Controller;
use App\Entity\Photo;
use App\Form\PhotoType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class PhotoController extends AbstractController
{
#[Route('/upload', name: 'upload')]
public function upload(Request $request): Response
{
$photo = new Photo();
$form = $this->createForm(PhotoType::class, $photo);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// ファイルを保存する処理
return new Response('アップロード成功!');
}
return $this->render('photo/upload.html.twig', [
'form' => $form->createView(),
]);
}
}
6. Twigテンプレートでフォームを表示
Symfonyのテンプレートファイル(Twig)では、form_startやform_endを使ってフォームを簡単に表示できます。エラー表示も自動で行われます。
{{ form_start(form, {'attr': {'enctype': 'multipart/form-data'}}) }}
{{ form_row(form.imageFile) }}
<button type="submit" class="btn btn-primary">アップロード</button>
{{ form_end(form) }}
7. バリデーションエラーの例
たとえば、画像のファイルサイズが5MBを超えた場合、次のようなメッセージが表示されます。
画像サイズは5MB以下にしてください。
また、JPEGやPNG以外のファイルをアップロードしようとすると、次のようなエラーになります。
JPEGまたはPNG形式の画像をアップロードしてください。
8. PDFやZIPなど画像以外のファイルに制限したいときは?
画像ではなく、PDFやZIPなどの一般的なファイルアップロードに対して制限をかけたいときは、@Assert\Fileを使えばOKです。
#[Assert\File(
maxSize: "10M",
mimeTypes: ["application/pdf", "application/zip"],
mimeTypesMessage: "PDFまたはZIPファイルをアップロードしてください。"
)]
このように、Symfonyではファイルの種類・サイズ・必須チェックを簡単に設定することができます。