Laravel file uploads


File Uploads in Laravel

Laravel makes handling file uploads simple by providing convenient methods to manage files in forms, store them in a desired location, and validate them. Here’s a detailed guide on how to handle file uploads in Laravel.

1. Creating the Form for File Upload

The first step is to create a form that allows users to upload a file. In Laravel, the enctype="multipart/form-data" attribute is essential for file uploads.

Example: Basic File Upload Form in Blade

<form action="{{ route('file.upload') }}" method="POST" enctype="multipart/form-data"> @csrf <div> <label for="file">Choose a file:</label> <input type="file" name="file" id="file"> </div> <button type="submit">Upload File</button> </form>

In this example:

  • @csrf: This directive adds a CSRF token to the form for security.
  • enctype="multipart/form-data": This ensures that file data can be submitted to the server.
  • input type="file": This creates a file input field.

2. Handling File Upload in the Controller

Once the form is submitted, you can handle the file upload in the controller. The uploaded file will be available in the request object.

Example: File Upload Handling in the Controller

use Illuminate\Http\Request; class FileUploadController extends Controller { public function uploadFile(Request $request) { // Validate the file $request->validate([ 'file' => 'required|mimes:jpg,jpeg,png,pdf|max:2048', // Limit to 2MB and only specific file types ]); // Check if the file was uploaded if ($request->hasFile('file')) { // Get the file $file = $request->file('file'); // Generate a unique name for the file before saving $filename = time() . '_' . $file->getClientOriginalName(); // Save the file in the 'uploads' directory within 'storage/app/public' $filePath = $file->storeAs('uploads', $filename, 'public'); // Return a response or redirect return back()->with('success', 'File uploaded successfully!')->with('file', $filename); } return back()->withErrors('File not uploaded.'); } }

Here’s how the code works:

  • $request->validate(): This validates the uploaded file, ensuring it meets the required constraints (file type, size, etc.).
  • $request->hasFile('file'): This checks if the file is present in the request.
  • $request->file('file'): This retrieves the uploaded file object.
  • storeAs(): This method stores the file in a specific directory with a custom filename. In this case, the file is stored in the uploads directory inside storage/app/public.

3. Configuring Filesystem and Storage

By default, Laravel uses the storage directory for storing files. To make these files accessible via the web, you need to create a symbolic link between the storage folder and the public folder.

Step 1: Creating a Storage Link

Run the following Artisan command to create the symbolic link:

php artisan storage:link

This creates a symbolic link from public/storage to storage/app/public, allowing files in storage/app/public to be accessed from the browser.

Step 2: File Storage Configuration

In the config/filesystems.php file, you can configure your storage settings. The default disk is usually set to local:

'disks' => [ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', ], ],

This configuration ensures that files stored using the public disk are accessible publicly.

4. Displaying Uploaded Files

Once the file is uploaded, you may want to display or provide a download link to the file.

Example: Displaying the Uploaded File

If you store the file in the public directory, you can display the file using the URL provided by the storage system:

@if(session('file')) <div> <p>File Uploaded: <a href="{{ asset('storage/uploads/' . session('file')) }}" target="_blank">{{ session('file') }}</a></p> </div> @endif
  • asset('storage/uploads/' . session('file')): This generates the public URL for the uploaded file.

5. File Validation

When handling file uploads, validation is essential to ensure the uploaded files meet certain criteria, such as file type, size, and more. Laravel provides several validation rules for file uploads:

  • required: Ensures that the file input is present.
  • mimes:jpg,jpeg,png,pdf: Restricts the file type to the specified MIME types.
  • max:2048: Limits the file size to 2 MB.

Example: File Validation

$request->validate([ 'file' => 'required|mimes:jpg,jpeg,png,pdf|max:2048', ]);

This validates that the uploaded file is either a jpg, jpeg, png, or pdf file and that its size does not exceed 2 MB.

6. File Deletion

To delete a file from the storage, you can use the Storage::delete() method.

Example: Deleting a File

use Illuminate\Support\Facades\Storage; if (Storage::exists('public/uploads/' . $filename)) { Storage::delete('public/uploads/' . $filename); }

This checks if the file exists in the uploads directory and deletes it if found.

7. Full Example: File Upload Workflow

Here’s an example of the complete workflow for uploading a file, validating it, storing it, and then displaying the uploaded file.

Step 1: Create the Route

Route::post('/upload', [FileUploadController::class, 'uploadFile'])->name('file.upload');

Step 2: Create the Controller

use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class FileUploadController extends Controller { public function uploadFile(Request $request) { // Validate file $request->validate([ 'file' => 'required|mimes:jpg,jpeg,png,pdf|max:2048', ]); // Upload file if ($request->hasFile('file')) { $file = $request->file('file'); $filename = time() . '_' . $file->getClientOriginalName(); $filePath = $file->storeAs('uploads', $filename, 'public'); return back()->with('success', 'File uploaded successfully!')->with('file', $filename); } return back()->withErrors('File not uploaded.'); } }

Step 3: Create the Blade View

@if(session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif <form action="{{ route('file.upload') }}" method="POST" enctype="multipart/form-data"> @csrf <div> <label for="file">Choose a file:</label> <input type="file" name="file" id="file"> </div> <button type="submit">Upload File</button> </form> @if(session('file')) <div> <p>File Uploaded: <a href="{{ asset('storage/uploads/' . session('file')) }}" target="_blank">{{ session('file') }}</a></p> </div> @endif