Handle file upload in Laravel 9

Handle file upload in Laravel 9
Handle file upload in Laravel 9

Just another day with Laravel coding tutorials, I will show you how to handle file upload in Laravel 9 quick and easy.

First, let’s start by creating a fresh new Laravel 9 project:

$ composer create-project laravel/laravel handle-file-upload

$ cd handle-file-upload

$ php artisan serve
Starting Laravel development server:

Visit browser at http://localhost:8000 to make sure there is no problem with the Laravel project.

To demonstrate the upload, we will:

  • Create two routes, one for showing the file upload form (GET), the other is to process the upload file (POST).
  • Create a controller UploadController with two methods, show method is to render the upload form Blade template, the other one process method is to process the upload file.
  • Create a view for upload form.

Let’ start by adding the routes into routes/web.php file:

// file: routes/web.php

Route::get('/', function () {
    return view('blog.petehouston.com - Handle file upload in Laravel 9');

// Add following two routes:
Route::get('/upload', [\App\Http\Controllers\UploadController::class, 'show']);
Route::post('/upload', [\App\Http\Controllers\UploadController::class, 'process']);

Then create the UploadController:

$ php artisan make:controller UploadController

The command will generate the controller file under app/Http/Controllers directory. We start with this basic code for the controller:

// file: app/Http/Controllers/UploadController.php


namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UploadController extends Controller
    public function show()
        // TODO
    public function process(Request $request)
        // TODO

For the first method show(), we will simply render a view named upload which shows the upload form.

// file: app/Http/Controllers/UploadController.php

    public function show()
        return view('upload');

That said, we need to create a Blade template resources/view/upload.blade.php with upload HTML code.

<!doctype html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>blog.petehouston.com - Handle File Upload in Laravel 9</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
        #main {
            margin-top: 200px;

<div class="container" id="main">
    <div class="row align-items-center">
        <div class="col offset-md-3 col-md-6 align-self-center">
            <h1>Handle file upload in Laravel 9</h1>
            <hr />
                <div class="alert alert-success">
                    {{ session()->get('message') }}
            <form method="post" action="/upload" enctype="multipart/form-data">
                <div class="mb-3">
                    <input class="form-control" type="file" name="myFile" required>

                <button type="submit" class="btn btn-primary mb-3 px-5">Upload</button>



For quick demonstration purpose, I use Bootstrap 5 to style the UI.

The form UI is ready, and we can update the UploadController::process() method:

// file: app/Http/Controllers/UploadController.php
    public function process(Request $request)
        $uploadedFile = $request->file('myFile');

        $uploadedFile->move(public_path('/uploads'), $uploadedFile->getClientOriginalName());

        return back()->with('message', 'File ' . $uploadedFile->getClientOriginalName() . ' has been uploaded successfully!');

Let’s elaborate each line of code.

  • $request->file('myFile') is called to get an instance of Illuminate\Http\UploadedFile from the form input having name=myFile. If you take a look at the upload.blade.php Blade form, you’ll notice that the form input name is name="myFile".
  • $uploadedFile->getClientOriginalName() will return the original name of the upload file.
  • public_path() returns the path to /public directory, and if we put in a path name as parameter, it will become a subpath of public. In this case, our uploaded file will be saved under public/uploads directory.
  • Finally, the code responds back with a successful upload message.

Restart the local server and test the upload process by visiting the url http://localhost:8000/upload on the browser.

Well done, you have learned how to handle file upload in Laravel 9.

If you have any problem, take a look at the Github repository demo code of this tutorial, https://github.com/petehouston/laravel-9-tutorials-code/tree/dev/handle-file-upload