How to upload a PDF file in Laravel in the best way?

Laravel allows us to easily upload a PDF file and many other types. For example doc, docx, csv, txt, png, gif, zip, etc. using file upload feature. Therefore, we can add validation rules to allow only particular file formats in the Laravel. Let’s go through the complete steps to upload PDF’s in Laravel 9.

Step 1: Laravel 9 Update and Create Application

composer create-project laravel/upload_pdf:^9.0 demo_app

You can specify the version number as 9.0, for Laravel 9 project.

Note: Laravel 9 installations require PHP 8.0.

Step 2: Create new Routes

To link pages in a Laravel application, we always need routes. Add them in the routes/web.php file.

<?php
 
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UploadPDFController;
 
Route::get('file-upload', [ UploadPDFController::class, 'getUploadPDFForm' ])->name('get.uploadPDF');
Route::post('file-upload', [ UploadPDFController::class, 'save' ])->name('save.file');

Step 3: Create new Controller

An UploadPDFController has the two methods that are added in the routes file. 

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
 
class UploadPDFControllerextends Controller
{
    public function getUploadPDFForm()
    {
        return view('file-upload');
    }
 
    public function save(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:pdf,xlxs,xlx,docx,doc,csv,txt,png,gif,jpg,jpeg|max:2048',
        ]);
 
        $fileName = $request->file->getClientOriginalName();
        $filePath = 'uploads/' . $fileName;
 
        $path = Storage::disk('public')->put($filePath, file_get_contents($request->file));
        $path = Storage::disk('public')->url($path);
 
        // Perform the database operation here
 
        return back()
            ->with('success','File has been successfully uploaded.');
    }
}

The getUploadPDFForm() funtion returns the view where a user can upload any file. Here the validate function assures that file type is a PDF. The same logic can be applied for other file types mentioned besides the mimes. However, for doc or docx you need to create a mimes.php inside config directory.

To validate doc, docx you need to create mimes.php in config directory and add the following content.

Step 3: Create new Blade file

A blade or view file is required where a user can upload the file. This is like an HTML page for the user.

<!DOCTYPE html>
<html>
   <head>
      <title>Laravel 9 Upload PDF Tutorial With Example- Scratchcoding.dev</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
   </head>
   <body>
      <div class="container">
         <div class="panel panel-primary">
            <div class="panel-heading">
               <h2>Laravel 9 Upload PDF Tutorial With Example</h2>
            </div>
            <div class="panel-body">
               @if ($message = Session::get('success'))
                   <div class="alert alert-success alert-block">
                      <button type="button" class="close" data-dismiss="alert">×</button>
                      <strong>{{ $message }}</strong>
                   </div>
               @endif
 
               @if (count($errors) > 0)
               <div class="alert alert-danger">
                  <strong>Oops!</strong> There were some problems with your input.
                  <ul>
                     @foreach ($errors->all() as $error)
                     <li>{{ $error }}</li>
                     @endforeach
                  </ul>
               </div>
               @endif
 
               <form action="{{ route('save.file') }}" method="POST" enctype="multipart/form-data">
                  @csrf
                  <div class="row">
                     <div class="col-md-6">
                        <input type="file" name="file" class="form-control"/>
                     </div>
                     <div class="col-md-6">
                        <button type="submit" class="btn btn-success">Upload File...</button>
                     </div>
                  </div>
               </form>
            </div>
         </div>
      </div>
   </body>
</html>

The blade file above views the upload file option to the user. In addition, it has two separate divs that pop up required messages. One for success and one for error. The error directive will display any error messages.

The above code allows you to upload a PDF file and any other file types mentioned with the required keyword inside the validate function. AJAX uploads a file without reloading a page. Read here for how to use the AJAX method to upload a file.