Handling file uploads is a common requirement in almost any web application. Whether users are uploading avatars, documents, or media files, having a secure and structured way to handle these assets is crucial.
Laravel provides a powerful and abstracted filesystem via Flysystem, making it incredibly simple to store files locally or on cloud storage platforms like Amazon S3. In this guide, we'll build a comprehensive file upload and management system.
Step 1: Configuration & Storage Link
By default, Laravel stores uploaded files in the storage/app/public directory if you use the public disk. To make these files accessible from the web, you need to create a symbolic link from public/storage to storage/app/public.
php artisan storage:link
Step 2: Creating the Upload Form
Let's create a simple HTML form that allows users to select and upload a file. The key here is the enctype="multipart/form-data" attribute, which is required for file uploads.
<form action="{{ route('files.upload') }}" method="POST" enctype="multipart/form-data">
@csrf
<div>
<label for="file">Choose File</label>
<input type="file" name="file" id="file" required>
</div>
<button type="submit">Upload</button>
</form>
Step 3: Handling the Upload and Validation
In our controller, we need to validate the incoming file to ensure it meets our security criteria (e.g., file type, size limits), and then store it.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
public function upload(Request $request)
{
$request->validate([
'file' => 'required|file|mimes:jpg,png,pdf,docx|max:2048',
]);
if ($request->file('file')->isValid()) {
// Generate a unique name or use the original name
$path = $request->file('file')->store('uploads', 'public');
// Save $path to database if needed
// File::create(['path' => $path]);
return back()->with('success', 'File uploaded successfully! Path: ' . $path);
}
return back()->withErrors('File upload failed.');
}
}
Step 4: Retrieving and Displaying Files
To display an uploaded image or provide a download link, you can use the Storage::url() method, which works smoothly with the symbolic link we created earlier.
<!-- Displaying an image -->
<img src="{{ Storage::url($path) }}" alt="Uploaded Image">
<!-- Download Link -->
<a href="{{ Storage::url($path) }}" download>Download File</a>
Step 5: Deleting Files
Managing files also means allowing users to delete them to free up space. Laravel makes deletion just as easy as storing.
public function destroy($path)
{
if (Storage::disk('public')->exists($path)) {
Storage::disk('public')->delete($path);
return back()->with('success', 'File deleted.');
}
return back()->withErrors('File not found.');
}
Conclusion
Laravel’s filesystem abstraction turns complex file handling operations into elegant, readable code. By always validating uploads and utilizing Laravel's built-in storage methods, you can ensure your application handles files securely and efficiently.