file — アップロードされた「ファイル」であることを確認する

validation
  • カテゴリ: validation
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: バリデーションルール: file
  • 関連: image, mimes, mimetypes, extensions
  • 変更履歴: 大きな仕様変更なし(従来どおり UploadedFile かどうかを検証)

要点(TL;DR)

  • 何に使うか:入力が HTTP アップロードされたファイルかどうかを判定する
  • 最低限の使い方'avatar' => ['required', 'file']
  • よくある罠
    • file だけでは拡張子・MIMEタイプ・サイズ制限は 一切かからない
    • <form>enctype="multipart/form-data" を付け忘れると常に失敗
    • Base64 文字列や URL には使えない(アップロードファイル専用)

概要

file ルールは、その入力が Illuminate\Http\UploadedFile としてアップロードされているかを検証するシンプルなルールです。
ファイルアップロード項目の「土台」として使い、タイプ制限は mimes / mimetypes / image、サイズ制限は size / max / min などと組み合わせて使うのが基本です。
フォームの enctype 設定ミスや、テキスト入力にファイルルールを当ててしまうミスを早期に検出できます。

構文 / シグネチャ

// 文字列形式
'field' => 'file'

// 配列形式(推奨)
'field' => ['file']

// 他ルールとの組み合わせ
'field' => ['required', 'file', 'mimes:pdf,docx', 'max:2048']

引数

file ルール自体に引数はありません。

引数必須既定値説明
なし

戻り値

  • バリデーション全体としては bool(通過/失敗)
  • file ルール単体は「指定フィールドが UploadedFile かどうか」をチェックして true/false

例外 / 副作用

  • コントローラで request()->validate() を使っている場合、失敗すると Illuminate\Validation\ValidationException がスローされ、前ページにリダイレクトされるのが典型パターン。
  • file ルール自体にはファイル移動・削除などの副作用はありません(実際の保存は store() などで行う)。

使用例

最小例

アップロードされたファイルであることだけを確認する例。

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/upload', function (Request $request) {
    $validated = $request->validate([
        'attachment' => ['required', 'file'],
    ]);

    // ここまで来れば attachment は UploadedFile であることが保証される
    $path = $request->file('attachment')->store('attachments');

    return response()->json([
        'path' => $path,
    ]);
});

ポイント:

  • required と組み合わせて「必須 + ファイル」であることを保証。
  • サイズやタイプの制限はこの例では付けていない(最小例)。

実務例:PDF レポートのみ受け付け、サイズ制限つき

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/reports', function (Request $request) {
    $validated = $request->validate([
        'report_file' => [
            'required',
            'file',             // アップロードファイルであること
            'mimes:pdf',        // 拡張子が .pdf
            'max:5120',         // 最大 5MB(KB 単位)
        ],
    ]);

    // 保存
    $path = $request->file('report_file')->store('reports');

    // DB にパスを保存するなどの処理…
    // Report::create([...]);

    return redirect()->back()->with('status', 'レポートをアップロードしました。');
});

実務ポイント:

  • file で「ファイルであること」を保証しつつ、mimes / max で実務要件を表現。
  • PDF 以外は弾きたいケースでよく使う組み合わせ。

よくある落とし穴・注意

  • file だけでは何も制限しない
    • サイズ制限は max / min / size を必ず組み合わせる。
    • 種類制限は mimes / mimetypes / image / extensions などと併用する。
  • フォームの enctype を忘れて常に失敗
    • <form method="POST" enctype="multipart/form-data"> を忘れると、ファイルがテキスト扱いになり file ルールが常に失敗する。
  • Base64 文字列・URL には不適
    • file は HTTP アップロードされたファイル専用。API で Base64 を受ける場合などは別設計が必要。
  • nullable と組み合わせるときの挙動
    • 'file_field' => ['nullable', 'file'] とした場合、未送信なら file はチェックされないが、中途半端な値(文字列など)が来るとエラーになる。

代替・関連APIとの比較

  • file
    • 「アップロードされたファイルであること」だけを保証。タイプ・拡張子・サイズはノーチェック。
  • image
    • file + 画像であること(jpeg,png,bmp,gif,svg,webp など)を保証。画像アップロードならこちらが基本。
  • mimes:xxx,yyy
    • 拡張子ベースでタイプを制限。ユーザーが見る拡張子ベースで指定したいときに便利。
  • mimetypes:text/plain,application/pdf
    • MIMEタイプベースでより厳密に制限したいときに使う。
  • extensions:pdf,docx
    • Laravel 11 以降で使える、拡張子ベースの制限ルール。mimes よりも「実際の拡張子」チェック寄り。

選定基準の目安

  • まず file は「ファイル項目」であれば基本的に付ける。
  • 画像専用 → imagefile を個別に書かなくてもよい)。
  • 「PDF だけ」など拡張子ベース → file + mimes もしくは extensions
  • API などで MIME を重視 → file + mimetypes

テスト例(Pest)

<?php

use Illuminate\Support\Facades\Validator;
use Illuminate\Http\UploadedFile;

it('accepts uploaded files with the file rule', function () {
    $file = UploadedFile::fake()->create('document.txt', 10); // 10KB

    $validator = Validator::make([
        'attachment' => $file,
    ], [
        'attachment' => ['required', 'file'],
    ]);

    expect($validator->passes())->toBeTrue();
});

it('fails when value is not an uploaded file', function () {
    $validator = Validator::make([
        'attachment' => 'not-a-file',
    ], [
        'attachment' => ['required', 'file'],
    ]);

    expect($validator->fails())->toBeTrue();
});

トラブルシュート(エラー別)

症状/エラー原因対処
「The attachment must be a file.」と表示されるフォームの enctypemultipart/form-data になっていない/フィールド名のミスフォームの enctype を修正し、name 属性とバリデーションのキーを一致させる
画像をアップしたのに種類エラーが出るfile のみで imagemimes を付け忘れている画像専用なら image を追加するか、許可する拡張子を mimes で指定する
サイズ制限が効いていないfile だけ指定していて max / size などを付けていないmax:2048 などのルールを追加する
API で JSON を送ると常に失敗するJSON ボディの文字列に file を当てているファイルアップロードエンドポイントと JSON API を分ける、または別の形式のバリデーションに変更する

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする