- カテゴリ: validation
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド: validation rule
image - 関連:
file/mimes/mimetypes/dimensions/extensions - 変更履歴: 旧バージョンでは JPEG 判定まわりの不具合報告あり(Laravel 8 以降で MIME 判定が改善)(Qiita)
要点(TL;DR)
- 何に使うか:アップロードされたファイルが「画像ファイルかどうか」をサクッと判定したいときに使う。(Laravel)
- 最低限の使い方:
$request->validate([ 'avatar' => ['required', 'image'], ]); - よくある罠
<form>にenctype="multipart/form-data"を付け忘れて常に失敗するimageだけだとサイズ・拡張子・縦横比などは制限されない- PHP / サーバーのアップロード制限で「The file failed to upload.」になる(Qiita)
概要
image ルールは、アップロードされたファイルが一般的な画像 MIME タイプ(jpeg, png, bmp, gif, webp, svg 等)かどうかを検証します。(Laravel)
画像アップロードフォームのバリデーションでほぼ必須となる基本ルールで、max や dimensions などと組み合わせて使うのが実務では一般的です。(Laravel News)
構文 / シグネチャ
// シンプルな書き方
'field' => 'image';
// 配列記法
'field' => ['image'];
// 他ルールとの組み合わせ
'field' => ['required', 'image', 'max:2048'];
引数
image ルール自体には引数はありません。
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| なし | – | – | – | image は単独で完結するルール |
戻り値
- 型:
bool(バリデーション内部的にはtrue/false) - 意味: 対象フィールドが「アップロードされた画像ファイル」であれば
true。そうでなければfalseとなり、通常はValidationExceptionが投げられます。
例外 / 副作用
- 例外
- コントローラで
$request->validate()を使うと、失敗時にIlluminate\Validation\ValidationExceptionがスローされ、直前ページへリダイレクト+エラーメッセージがフラッシュされる。(Laravel)
- コントローラで
- 副作用
- アップロードそのものは PHP/SAPI が行う。
imageルールは「アップロード済みの一時ファイル」を検査するのみ。
- アップロードそのものは PHP/SAPI が行う。
使用例
最小例
ユーザーのアイコン画像をアップロードする簡単な例。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
public function update(Request $request)
{
// バリデーション
$validated = $request->validate([
'avatar' => ['required', 'image'], // 画像ファイルであることだけを保証
]);
// ファイル保存(storage/app/public/avatars に保存)
$path = $request->file('avatar')->store('avatars', 'public');
// ユーザー情報を更新
$request->user()->update([
'avatar_path' => $path,
]);
return back()->with('status', 'プロフィール画像を更新しました。');
}
}
<!-- Blade 側のフォーム例 -->
<form method="POST" action="{{ route('profile.update') }}" enctype="multipart/form-data">
@csrf
<input type="file" name="avatar" accept="image/*">
<button type="submit">保存</button>
</form>
ポイント:
<form>にenctype="multipart/form-data"を必ず付与accept="image/*"はフロント側の補助(バリデーションには依存しない)
実務例:サイズ・拡張子・縦横比をまとめてチェック
サムネイル画像として横長(16:9)、2MB までの JPEG/PNG のみ許可する例。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Validation\Rules\File;
class PostController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'content' => ['required', 'string'],
'thumbnail' => [
'required',
'image', // 画像であること
'mimes:jpeg,jpg,png', // 拡張子・MIME を限定
'max:2048', // 2MB まで(KB 単位)
'dimensions:ratio=16/9', // 16:9 のみ許可
],
]);
$path = $request->file('thumbnail')->store('thumbnails', 'public');
// DB 保存など
// Post::create([...]);
return redirect()->route('posts.index')
->with('status', '記事を登録しました。');
}
}
imageだけでは「画像っぽいファイル」かどうかしか判定しないため、mimes/max/dimensionsと組み合わせるのが定番です。(Laravel Daily)
よくある落とし穴・注意
- フォームの
enctypeを忘れているmultipart/form-dataがないと、サーバー側にはファイルが届かずimage以前にrequiredで落ちます。
- ファイルサイズ制限は別ルール
imageにはサイズ制限は含まれません。max:2048などを明示的に指定する必要があります。(Stack Overflow)
- MIME と拡張子の制御
- 画像であれば何でも良いのか、JPEG/PNG のみにしたいのかで
mimes/mimetypesを併用します。
- 画像であれば何でも良いのか、JPEG/PNG のみにしたいのかで
- PHP / Web サーバーのアップロード制限
upload_max_filesize/post_max_size/client_max_body_size(Nginx)などで制限を超えると、Laravel 側では「The file failed to upload.」になりがちです。(Qiita)
- 古い Laravel で JPEG 判定バグ
- 7 以前では
imageルールと JPEG 周りに不具合がある報告があり、mimes:jpeg,jpg,png,...を明示することで回避するケースがありました。Laravel 8+ / 12 では改善済みです。(Qiita)
- 7 以前では
代替・関連APIとの比較
| ルール | 役割 | 主な使いどころ |
|---|---|---|
image | 画像ファイルであるかどうか(共通の画像 MIME) | 「とりあえず画像かどうか」を判定したいときの基本 |
file | アップロードされたファイル全般 | 画像以外(PDF, ZIP など)も扱う場合のベース |
mimes:jpeg,png,... | 拡張子 / MIME を限定 | 許可する形式を厳密に制御したいとき |
mimetypes:image/jpeg,... | 正確な MIME タイプ指定 | API など MIME を厳格にチェックしたいとき |
dimensions | 画像の幅・高さ・比率を制御 | サムネイル・バナーなど、デザイン上の制約がある画像 |
選び方の目安
- 「画像かどうか」だけで良い →
image - 「JPEG/PNG だけ」など形式も制限したい →
image+mimes - 「サムネイルは 16:9 だけ」などレイアウト前提 →
image+dimensions - 「画像も含めファイル全般を扱うフォーム」 →
fileと条件分岐 or フィールド分割
テスト例(Pest)
<?php
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Validator;
it('accepts valid image file', function () {
$file = UploadedFile::fake()->image('avatar.jpg', 300, 300);
$validator = Validator::make(
['avatar' => $file],
['avatar' => ['required', 'image']]
);
expect($validator->passes())->toBeTrue();
});
it('rejects non-image file', function () {
$file = UploadedFile::fake()->create('document.pdf', 100, 'application/pdf');
$validator = Validator::make(
['avatar' => $file],
['avatar' => ['required', 'image']]
);
expect($validator->fails())->toBeTrue();
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
The avatar must be an image. | image ルールに失敗。そもそもファイルが画像ではない/アップロードされていない | 対象フィールド名の確認、enctype 設定、accept="image/*" で UI 補助 |
The file failed to upload. | PHP / Web サーバー側のアップロードサイズやタイムアウト制限に抵触 | php.ini の upload_max_filesize・post_max_size、Nginx/Apache 側の制限を見直す(Qiita) |
null なのにエラーになる | フィールドが任意なのに nullable を付けていない | ルールに nullable を追加(`nullable |
| JPEG なのにエラーになる(古い案件) | 古い Laravel バージョンで JPEG 判定まわりのバグ | Laravel をアップデート、または mimes:jpeg,jpg,png,... を明示的に追加(Qiita) |
参考リンク
- Laravel 12.x Official Docs — Validation
https://laravel.com/docs/12.x/validation (Laravel) - Laravel News — Image Dimension Validation with
dimensionsRule
https://laravel-news.com/image-dimension-validation-rule (Laravel News) - Laravel Daily — Four Laravel Validation Rules for Images and Photos
https://laraveldaily.com/post/four-laravel-validation-rules-for-images-and-photos (Laravel Daily) - Qiita — フォームバリデーションルール
image使用時の注意点
https://qiita.com/derasado/items/68529e65b063b741b37d (Qiita) - Qiita — 「The file failed to upload.」エラーの解説
https://qiita.com/miriwo/items/acf349a110d4c4ce16cc (Qiita)

