File uploads — $request->file(), store(), storeAs()
Concept
File uploads in Laravel are handled through $request->file() which returns Illuminate\Http\UploadedFile instances (extending Symfony's UploadedFile). This object wraps PHP's $_FILES data with a rich OOP API for validation and storage.
$request->file(string $key): Returns an UploadedFile or null. For multiple files (input name="photos[]"), returns an array.
$request->hasFile(string $key): True if the key contains an uploaded file (not just a form field).
UploadedFile methods:
->isValid(): True if upload succeeded without errors.->getClientOriginalName(): Original filename from the browser — NEVER use this as the stored filename without sanitization.->getClientOriginalExtension(): Client-reported extension — NEVER trust this for MIME type.->getMimeType(): Detected MIME type from file content (usesfinfo).->getSize(): File size in bytes.->getError(): Upload error code (0 = success).
->store(string $path, string $disk = 'default'): Moves the file to storage using Laravel's filesystem. Generates a unique filename. Returns the stored path. Equivalent to Storage::put().
->storeAs(string $path, string $name, string $disk = 'default'): Store with a specific filename.
->storePublicly(string $path): Store in a publicly accessible location.
Code Example
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class AvatarController extends Controller
{
public function upload(Request $request): JsonResponse
{
$request->validate([
'avatar' => [
'required',
'file',
'image', // validates as image (MIME check)
'mimes:jpg,jpeg,png,webp',
'max:2048', // max 2MB (in kilobytes for max rule)
'dimensions:min_width=100,min_height=100,max_width=2000',
],
]);
$file = $request->file('avatar');
// Validate upload success
if (!$file->isValid()) {
return response()->json(['error' => 'Upload failed'], 422);
}
// Store on S3 (or configured disk) with auto-generated unique name
$path = $file->store('avatars', 's3'); // "avatars/generated-uuid.jpg"
// Or store with a specific name
$userId = auth()->id();
$ext = $file->getClientOriginalExtension(); // "jpg" — use as extension only
$path = $file->storeAs('avatars', "$userId.$ext", 's3');
auth()->user()->update(['avatar_path' => $path]);
return response()->json([
'path' => $path,
'url' => \Illuminate\Support\Facades\Storage::disk('s3')->url($path),
]);
}
public function multiple(Request $request): JsonResponse
{
$request->validate([
'photos' => 'required|array|max:5',
'photos.*' => 'image|max:5120',
]);
$paths = [];
foreach ($request->file('photos') as $photo) {
$paths[] = $photo->store('photos', 'public');
}
return response()->json(['paths' => $paths]);
}
}