Laravel Upgrade: The easiest way to Upgrade your Laravel Application From any version(5.x, 6.x) to 7.x in no time

Root User

Apr 28, 2020

It's cumbersome to maintain your legacy projects when you are not actively working on it. In this article I will explain the easiest way to upgrade your laravel application from any version (5.x, 6.x) to 7.x or may from version 4.x to 7.x in no time. I will consider my laravel app Esikai.com which is in laravel version 5.8.37 while explaining further.

To check the laravel version of your application, RUN the following command

php artisan -V

The upgrade process can divide into two steps.

  1. First Step: Upgrade your dependency
  2. Second Step: Address the breaking changes.

Step 1: Upgrade your dependency

This is my own rule to upgrade any laravel application, through my years of experience. Nobody has taught this method in anywhere. To start the upgrade process, we have to know two types of dependency.

  1. Framework dependency
  2. Application dependency

Framework Dependency This is the minimum dependency that your laravel application needs to run. These dependency are dependency that are installed when you first installed your laravel application. For example: the fresh installed aravel version 7.x, would have composer.json file like this.

// composer.json files
{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0"
    },
    "require-dev": {
        "facade/ignition": "^2.0",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^4.1",
        "phpunit/phpunit": "^8.5"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

In this composer.json file, the require and require-dev section defines the framework dependency or in another words these are the minimum requirement that your laravel 7.x application require to run successfully.

Note I am upgrading my Laravel 5.8 application as well.

But If I open composer.json file of my application, it would be:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": "^7.1.3",
        "aammui/laravel-media": "0.1.1",
        "aammui/laravel-taggable": "0.4.4",
        "aammui/role-permission": "dev-master",
        "barryvdh/laravel-cors": "^0.11.0",
        "fideloper/proxy": "^4.0",
        "folklore/graphql": "~1.0.0",
        "laravel/framework": "5.8.*",
        "laravel/socialite": "^3.0",
        "laravel/tinker": "~1.0",
        "livewire/livewire": "^0.7.4",
        "myclabs/php-enum": "^1.7",
        "pusher/pusher-php-server": "~2.6",
        "spatie/pdf-to-image": "^2.0",
        "thiagoalessio/tesseract_ocr": "^2.9"
    },
    "require-dev": {
        "aammui/ddd": "dev-master",
        "barryvdh/laravel-debugbar": "^3.2",
        "barryvdh/laravel-ide-helper": "^2.6",
        "beyondcode/laravel-dump-server": "^1.0",
        "filp/whoops": "^2.0",
        "fzaninotto/faker": "^1.4",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^3.0",
        "phpunit/phpunit": "^7.5"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
            "app/Http/helpers.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        },
        "files": [
            "tests/helpers.php"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi",
            "@php artisan vendor:publish --tag=livewire:config"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    }
}

Application Dependency These are the dependency which I have added while writing my application For example: I needed role-permission feature in my application so I have added it from somewhere(role-permission) and now all that packages that I have added into my application are the application dependency.

How to find Application Dependency

My upgrading application is in version 5.8.37 so let's check the framework dependency of version Laravel 5.8. in github

// composer.json 
{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "5.8.*",
        "laravel/tinker": "^1.0"
    },
    "require-dev": {
        "beyondcode/laravel-dump-server": "^1.0",
        "filp/whoops": "^2.0",
        "fzaninotto/faker": "^1.4",
        "mockery/mockery": "^1.0",
        "nunomaduro/collision": "^3.0",
        "phpunit/phpunit": "^7.5"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

If I compare my Laravel 5.8 and Fresh Laravel composer.json file, I will see the following difference in the require section.

Composer.json Comparison

and further comparing development dependency in require-dev section.

Comparing development Dependency

So comparing the above composer files my application dependencies are:

require Section

"aammui/laravel-media": "0.1.1",
"aammui/laravel-taggable": "0.4.4",
"aammui/role-permission": "dev-master",
"barryvdh/laravel-cors": "^0.11.0",
"folklore/graphql": "~1.0.0",
"laravel/socialite": "^3.0",
"livewire/livewire": "^0.7.4",
"myclabs/php-enum": "^1.7",
"pusher/pusher-php-server": "~2.6",
"spatie/pdf-to-image": "^2.0",
"thiagoalessio/tesseract_ocr": "^2.9"

And Development dependency are require-dev section

"aammui/ddd": "dev-master",
"barryvdh/laravel-debugbar": "^3.2",
"barryvdh/laravel-ide-helper": "^2.6",

So we found our application dependencies. Now save this Application dependency safe in somewhere.

Upgrade to Laravel version 7.x from 5.8

(You can upgrade any version of Laravel to 7.x directly without any worried). To begin the upgrade process We will first upgrade the Framework Dependency to Laravel Version 7.x. So Let's Compare the Framework dependency in Laravel 5.8 and 7.x

Compare Framework dependency between 5.6 and 7.x)

As you see almost all the dependency has been changed while moving to the version 7.x. So to upgrade Framework Dependency I simple delete my project composer.json and create new composer .json from the copy of laravel version 7.x.

[Note: Important point is you have to determine what are your application dependencies, and then you can create new composer.json files from latest laravel version ]

My new Composer.json file will be(Copy from Laravel Version 7.x).

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0"
    },
    "require-dev": {
        "facade/ignition": "^2.0",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^4.1",
        "phpunit/phpunit": "^8.5"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

Now save the file and execute the command in terminal.

composer update

Congratulations if update is successful your application is updated to laravel version 7.x. Meanwhile I got error about facade/ignition suggests installing laravel/telescope (^3.1) So I installed the telescope package.

composer require laravel/telescope

But I still got another error about

PHP Fatal error:  Declaration of App\Exceptions\Handler::report(Exception $exception) must be compatible with Illuminate\Foundation\Exceptions\Handler::report(Throwable $e) in /media/ellite/c4fe0452-ea69-4a2b-8a1f-7fdc3fc53744/Practise/aammui-original/app/Exceptions/Handler.php on line 33

I will see this in second steps let it be as it right now.

Now let's install our application dependency as: I removed the version number, because let composer choose the desired version for Laravel 7.x rather than searching manually.

composer require aammui/laravel-media
composer require aammui/laravel-taggable
composer require aammui/role-permission
composer require barryvdh/laravel-cor
composer require folklore/graphql
composer require laravel/socialite
composer require livewire/livewire
composer require myclabs/php-enum
composer require pusher/pusher-php-server
composer require spatie/pdf-to-image
composer require thiagoalessio/tesseract_ocr

Or You even can do as in one line I suggest to install at once

composer require aammui/laravel-media aammui/laravel-taggable aammui/role-permission barryvdh/laravel-cors folklore/graphql laravel/socialite livewire/livewire myclabs/php-enum pusher/pusher-php-server spatie/pdf-to-image thiagoalessio/tesseract_ocr

and don't forget to install development dependency with dev flag.

 composer require aammui/ddd 
 barryvdh/laravel-debugbar 
 barryvdh/laravel-ide-helper --dev

Although we updated all our dependencies to Laravel 7.x, Our application still has some error this is because of the breaking changes introduced by laravel framework on it's major release. So in next step we will look out how to address these errors.

Step 2: Address the breaking changes.

Every major release introduces some breaking change into the framework. So instead of reading all the documentation for the breaking changes from version to version I would suggest to follow the debugging process where we will handle each error rather than go through the documentation, because not every changes affect our application.

So, the above error was due to framework changes so I googled it and found the solution that I should paste this code into the app/Exceptions/Handler.php.

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
  /**
   * A list of the exception types that are not reported.
   *
   * @var array
   */
  protected $dontReport = [
      //
  ];

  /**
   * A list of the inputs that are never flashed for validation exceptions.
   *
   * @var array
   */
  protected $dontFlash = [
      'password',
      'password_confirmation',
  ];

  /**
   * Report or log an exception.
   *
   * @param  \Throwable  $exception
   * @return void
   *
   * @throws \Exception
   */
  public function report(Throwable $exception)
  {
      parent::report($exception);
  }

  /**
   * Render an exception into an HTTP response.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Throwable  $exception
   * @return \Symfony\Component\HttpFoundation\Response
   *
   * @throws \Throwable
   */
  public function render($request, Throwable $exception)
  {
      return parent::render($request, $exception);
  }
}

Now run composer install in terminal.

After addressing few numbers of exception, Now my application Esikai.com is successfully upgraded into Laravel 7.9.2

Conclusion

In this blog post, I have attempt to explain How to upgrade any Laravel application from any version to Laravel Latest version. While writing this article I have successfully upgraded my application to the latest version (i.e. Laravel 7.9.2 ). So It's not that hard to upgrade your laravel application, You just have to know your application dependency, and later should strong enough to bug your application. Thanks.

Related Articles