How to upload multiple files in Laravel

Updated: January 18, 2024 By: Guest Contributor Post a comment

Introduction

Laravel, known for its elegant syntax and robust features catering specifically to the needs of web application developers, includes a powerful file handling system. One common task in web applications is allowing users to upload multiple files at once. This tutorial aims to guide you through the process of implementing that feature using Laravel’s functionalities.

Prerequisites

Before we get started, make sure you have the following:

  • Laravel installed on your local development machine. If you don’t, see this tutorial: How to install Laravel on Windows and Mac.
  • Basic understanding of Laravel’s request handling
  • Familiarity with HTML forms and file inputs
  • A working instance of MySQL or another database supported by Laravel

Setting Up the Route and Controller

To begin, set up a route and controller that will handle the file upload request. Add the following to the routes/web.php file.

Route::post('/upload', 'FileUploadController@store');

Create a FileUploadController:

php artisan make:controller FileUploadController

Preparing the Database

To store file metadata, you’ll first need to create a migration for a new table. Run the following Laravel Artisan command to create a migration:

php artisan make:migration create_files_table

Edit the generated migration file in the database/migrations directory to define the schema:

Schema::create('files', function (Blueprint $table) {
    $table->id();
    $table->string('filename');
    $table->timestamps();
});

Then, run the migration:

php artisan migrate

Building the Form

In your view file, create the HTML form for file upload:

<form action="/upload" method="post" enctype="multipart/form-data">
    {{ csrf_field() }}
    <input type="file" name="files[]" multiple>
    <button type="submit">Upload Files</button>
</form>

Remember, setting the enctype to multipart/form-data is necessary for file uploads, and the multiple attribute on the file input allows multiple file selection.

Handling File Uploads

Inside FileUploadController, implement the storage logic to handle file upload.

public function store(Request $request)
{
    $request->validate(['files.*' => 'required|file|max:2048']);

    if ($request->hasfile('files')) {
        foreach ($request->file('files') as $file) {
            $filename = $file->getClientOriginalName();
            $file->storeAs('public/uploads', $filename);

            File::create([
                'filename' => $filename
            ]);
        }
    }

    return back()->with('success', 'Files have been uploaded.');
}

Validating Files

It’s important to validate each file to ensure they meet any specific requirements for your application. For instance, you could restrict file types or sizes:

$request->validate([
   'files.*' => 'required|file|mimes:jpg,bmp,png|max:5000'
]);

Storing Files

Once the files have passed validation, they are looped over and stored in the desired directory using Laravel’s built-in file storage system, which defaults to the storage/app/public directory. Here is where you might also handle file reference storage within the database:

foreach ($request->file('files') as $file) {
    $filename = $file->getClientOriginalName();
    $path = $file->store('uploads', 'public');

    File::create([
        'filename' => $path
    ]);
}

Using the store method will automatically generate a unique ID to prepend the file name, preventing filename conflicts. The public parameter signifies that it should be stored in the storage/app/public folder. You should run the following Artisan command to create the symbolic link:

php artisan storage:link

Displaying Uploaded Files

To retrieve and display uploaded files on a page, access the stored files using Laravel’s file storage abstraction:

$files = File::all();
foreach ($files as $file) {
    $url = Storage::url($file->filename);
    echo '<img src="'.asset($url).'" />';
}

Testing the Upload

Create a route to display the upload form:

Route::get('/upload/form', function () { 
   return view('upload_form'); 
});

Navigate to this route in your web browser, select multiple files and submit the form. If everything is set up correctly, your chosen files should be uploaded to the server and their references stored in the database.

Always ensure to implement proper error handling and user feedback for production applications.

Conclusion

Uploading multiple files in Laravel is straightforward, thanks to Laravel’s easy-to-use built-in file storage system. By following the steps outlined in this tutorial, you should be able to add this functionality to any Laravel application, adding a layer of interactivity and utility for your user base.