Upgrading From Laravel 5 to Laravel 8

Published 7 months ago 11 min read

In the past couple of weeks, I’ve had to update a few of my Laravel projects. I am incrementally upgrading them to the latest version of Laravel. However this is a guide for anyone who is looking to upgrade their Laravel Project from 5.6 to 8.

Disclaimer : There is already a well known paid package that does this. If you want to save some time and have some money to spend then check out Laravel Shift .

Right lets get to it!

  1. Before you start look through all the external packages you are using that aren’t part of the default Laravel installation, and ensure they have been updated for Laravel 8.x. Check through composer.json and through packagist to check the compatibility. If your project packages have been built by well known companies from the community such as Spatie, Tighten then you shouldn’t have much to worry about
  2. First things first, in your project we are going to create a new git branch:
    git checkout -b "upgrade/laravel-8"
  3. Go through your project’s composer.json files and check if there are any packages that are not being used and remove them.
  4. To help with this process we are going to create another separate blank Laravel 8 project using composer ( I know this is weird but follow along with me). This will create a laravel 8 project in a folder called “demo” :
    composer create-project --prefer-dist laravel/laravel:^8.0 demo
  5. Ensure you are running PHP 7.4 on your localised demo and existing project folders. If you are using Laravel Valet on MacOS, use the following commands on both your project and the demo project to localise your project to PHP 7.4 : valet isolate php@7.4 To set the PHP version.
    Henceforth, if you need to use composer then run valet composer and for valet php to run PHP.
  6. Run composer update (Remember if you are using Laravel Valet then do valet composer update).
  7. Go into the demo project and start a git repo and commit it as initial commit
  8. Replace the following dev dependencies in your existing composer.json if you have them as they are no longer used in the Laravel :
    "filp/whoops" was replaced with "facade/ignition": "^2.5" and "fzaninotto/faker" was replaced with "fakerphp/faker": "^1.9.1"
  9. Within the demo project, add the following repositories :
    • "laravel/helpers": "^1.6" This provides backwards compabitlity for helper functions that were in laravel 5.8 which have been put into Arr and Str. If you prefer to replace it manually across your project then here is the full list of methods that need replacing. Remember to import the classes if you decide to do this: use Illuminate\Support\Arr; and
      use Illuminate\Support\Collection;

      Method Name Replacement
      array_add Arr::add
      array_collapse Arr::collapse
      array_divide Arr::divide
      array_dot Arr::dot
      array_except Arr::except
      array_first Arr::first
      array_flatten Arr::flatten
      array_forget Arr::forget
      array_get Arr::get
      array_has Arr::has
      array_last Arr::last
      array_only Arr::only
      array_pluck Arr::pluck
      array_prepend Arr::prepend
      array_pull Arr::pull
      array_random Arr::random
      array_set Arr::set
      array_sort Arr::sort
      array_sort_recursive Arr::sortRecursive
      array_where Arr::where
      array_wrap Arr::wrap
      camel_case Str::camel
      ends_with Str::endsWith
      kebab_case Str::kebab
      snake_case Str::snake
      starts_with Str::startsWith
      str_after Str::after
      str_before Str::before
      str_contains Str::contains
      str_finish Str::finish
      str_is Str::is
      str_limit Str::limit
      str_plural Str::plural
      str_random Str::random
      str_replace_array Str::replaceArray
      str_replace_first Str::replaceFirst
      str_replace_last Str::replaceLast
      str_singular Str::singular
      str_slug Str::slug
      str_start Str::start
      studly_case Str::studly
      title_case Str::title
    • "laravel/ui": "3.4.6" which provides : The Bootstrap and Vue scaffolding provided by Laravel.

  10. Review your current project’s composer.json file and copy across any necessary required or dev dependencies that are not present in the demo project’s composer.json.
  11. For all the new dependencies you just copied from the above step replace the version number with “*” . I know this sounds crazy but i have tested with a repo which had over 20 packages and i can confirm it works. For example. I had a repository which had this:
    
      "barryvdh/laravel-dompdf": "*",
      "barryvdh/laravel-ide-helper": "*",
      "friendsofphp/php-cs-fixer": "*",
      "maatwebsite/excel": "*",
      "owen-it/laravel-auditing": "*",
      "plank/laravel-mediable": "*",
      "spatie/laravel-analytics": "*",
      "spatie/laravel-failed-job-monitor": "*",
      "spatie/laravel-permission": "*",
      "spatie/laravel-responsecache": "*",
      "tightenco/ziggy": "*",
      "tucker-eric/eloquentfilter": "*"
    
    
  12. Now run composer update and it should install most of the packages. If you have any problems, try and do a few packages at a time and keep adding more until you find the problematic one, skip that one and try and fix that at the end until you get a full working composer.json within the demo project with all your dependences.
  13. If you are using PHPStorm, you should now see the version that was installed and replace all of the “*” with the actual version and then copy it back into your demo projects composer.json file, otherwise use the composer.lock file to see which version is installed. If you want to save yourself some time here is a python script that will do it for you)
  14. Now you can easily copy composer.json file from the demo folder to your project.
  15. Once the above step is complete, in your current project, you can run composer update and ensure it installs properly. Sometimes if errors occur, I delete the composer.lock and vendor folder and try again with composer install
  16. At this point, it’s best to do a git commit to your project file (remember you should be in your upgrade/laravel-8 branch)
  17. Laravel Passport Projects: Passport::personalAccessClientId('Some Client Name'); was removed from Laravel Passport, so remove this from your app/Providers/AuthServiceProvider.php file. Then look within your oauth_clients database table, and copy the name and secret to your .env file :
    PASSPORT_PERSONAL_ACCESS_CLIENT_ID="Some Client Name"
    PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET="Secret From oauth_clients table for Some Client Name"
  18. Replace Handler.php at app/exceptions/Handler.php with the one within the demo project folder.
  19. Go to routes/web.php and replace any instances of $this-> with Route:: For example :
    
    // Authentication Routes...
    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
    $this->post('login', 'Auth\LoginController@login');
    $this->post('logout', 'Auth\LoginController@logout')->name('logout');
    

    to this – make sure you include use Illuminate\Support\Facades\Route; on top of the file

    // Authentication Routes...
    Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
    Route::post('login', 'Auth\LoginController@login');
    Route::post('logout', 'Auth\LoginController@logout')->name('logout');
    
  20. Rename your seeds folder to seeders within your database folder and namespace all of your seeders files with :
    <?php
    
    namespace Database\Seeders;
  21. In Laravel 8, factories are now classes that extend the base Laravel factory class. Namespace all of your ‘factories’ class :
  22. <?php
    
    

    namespace Database\Factories;

    and update all of your factories to a class based version like the one found with the demo project under database/factories/UserFactory.php

  23. Apply the has HasFactory trait to all your Models which have factories and use the HasFactory namepsace, look at the example found in the demo folder
  24. Update your session config file’s secure option will a fallback value of null :
    'secure' => env('SESSION_SECURE_COOKIE', null),
  25. Although this is mentioned in Laravel 9 Upgrade Guide, Within your app/Http/Middleware/TrustProxies.php file, update use Fideloper\Proxy\TrustProxies as Middleware to use Illuminate\Http\Middleware\TrustProxies as Middleware.
  26. If you use Bootstrap for your front end, you should add the following method call to the boot method of your application’s AppServiceProvider:
    
    use Illuminate\Pagination\Paginator;
     
    Paginator::useBootstrap();
    
  27. The users table has a new field called email_verified_at which gives you email verification functionality

    Therefore create a new migration file on your current project by typing php artisan make:migration add_email_verified_field_to_users_table with the following code :

    
        public function up()
        {
            Schema::table('users', function (Blueprint $table) {
                $table->timestamp('email_verified_at')->nullable()->after('email');
            });
        }
        
        public function down()
        {
            Schema::table('users', function (Blueprint $table) {
                $table->dropColumn('email_verified_at');
            });
        }
    
  28. Compare everything within the following folders from your demo project and copy all of the files from there into your current project. Certain functionalities may have changed but ensure you don’t blindly copy and retain certain functionality :
    • app
    • config
    • routes
  29. You should go through the official upgrade guides to see if anything has been missed that is specific to your project.
  30. Run composer update and make sure your project is now working as expected composer update.
  31. Update your gitignore file from the demo project.
  32. At this point if you have any problems, delete your composer.lock file and vendor directory and run composer install.
  33. Run phpunit and ensure all your tests are working (hopefully you have been writing them)!
  34. Do a git commit at this point within your project
  35. Up until this point we only concentrated on the php side of the upgrades. Now we are going to focus on the front end.

Front End changes from Laravel 5 to Laravel 8

  1. The best way to work through this is if you install the main framework such as vue or react first
  2. Go to the official npm website search the framework you are using i.e. vue or react and then find the latest version of your release version from your current project i.e. i had a project in react 17 so i ran npm i react@17.0.2 and npm i react-dom@17.0.2
  3. The default asset bundler is still Laravel Mix. However you need ensure your you put .vue() or .react() within your webpack dependencing on which package you use. Start by doing this in the demo project. Let’s say i am using react this is what my webpack.mix.js file would look like :
    
    mix.js('resources/js/app.js', 'public/js')
        .postCss('resources/css/app.css', 'public/css', [
            //
        ]).react();
    
  4. Now run npm install && npm run dev . This will install all the necessary packages related to getting React or Vue Working
  5. For React with Typescript install these packages :
    
    npm i @types/react @types/react-dom
    npm i ts-loader typescript @babel/preset-react --dev
    

    and For Vue :

    
    npm i vue@next vue-router vue-loader @vue/compiler-sfc 
    npm i typescript ts-loader  --dev
    

    Copy your tsconfig.json file from your project to the demo project

  6. Now copy some of your react/vue components into your resources folder and then configure webpack.mix.js file to render them using . Fix any errors you get start with minimal components.
    A React Setup Would look like this :

    
    const mix = require("laravel-mix");
    mix.ts("resources/js/app.tsx", "public/js").react();
    

    And the same vue version would look like this :

    
    const mix = require("laravel-mix");
    mix.ts("resources/js/app.tsx", "public/js").vue({ version: 3 })
    

    Now run npm install && npm run dev and ensure its working then run npm run prod to ensure production builds are working too

  7. If you are using tailwind css :
    
    npm i tailwindcss
    

    and your mix file would look like this :

    
    mix.postCss("resources/css/app.css", "public/css", [require("tailwindcss")]);
    

    Again repeat run npm install && npm run dev and ensure its working then run npm run prod to ensure production builds are working too

  8. Now do a git commit on your demo project
  9. Copy all of your js files into demo and ensure all of your components and files are rendering. Use the --legacy-peer-deps to install the correct packages accordingly: The are the three commands i repeated using during this process :
    
    npm i --legacy-peer-deps npm_package_name
    npm i --legacy-peer-deps npm_package_name --save-dev
    npm run dev
    npm run prod
    rm -rf node_modules package-lock.json
    

    Since this is a demo project you can safely delete the nodes_modules folder and package.json folder and test until you get this process right

  10. Once you have a working version replace your project’s webpack.mix.js with the one within the demo and run npm install && npm run dev followed be npm run build
  11. Now do a git commit of your upgrade/laravel-8 branch and create a PR for it.
  12. Deploy the branch on a testing environment and ensure it all works.

I wrote this guide as a simple reference when i am upgrading my old Laravel repositories. Hopefully these steps work for you.