
Migrating Legancy Laravel 4 project to Laravel 7
General steps to follow:
1 | New laravel project setup with latest laravel framework version. |
2 | namespace setup for whole app |
3 | composer.json migration |
3.1 | find correct version for all old packages in OLD and add in NEW project. |
3.2 | composer update |
3.3 | solving version confilicts on NEW |
3.4 | for old packages without matched new version, find substitutions and record them. As in the future we need to swap old ones with these new packages. |
4 | configuration file migration. |
4.1 | |
5 | change filters to middlewares |
5.1 | if filter is inside controller, keep middleware at the same place. If filter is in the route, change it to middleware on the same route. |
5.2 | use Response to return response if necessary in middleware. |
6 | refine namespace setup in composer.json. If psr-4 is not possible or may take a long time to implement, use classmap instead. Better not use psr-0. |
7 | copy old public folder to new public folder. do not copy index.php. |
8 | File is replaced with Storage, thus anywhere File is used should be replaced by Storage. |
Some specific ugrade/migration tips and tricks:
No | Issue | Reason | Solution | sphere of influence |
1 | Input class doesn’t support | Input is deprecated. | Changed to use Http Request Class use Illuminate\Http\Request; $request::all() to get parameters. | Global |
2 | filter doesn’t work | filter is deprecated. | changed to use middleware | Global, routes |
3 | For All models extends Eloquent => extends Model | Model | ||
4 | UserInterface, RemindableInterface doesn’t support | UserInterface, RemindableInterface are deprecated. | remove UserInterface, RemindableInterface and related codes | User Model |
5 | can’t get user id | The type of primary key UserId in user table is string. | In User Model, need to add below $keyType = ‘string’; | Model |
6 | when testing, pushToGoogleAnalytics() function will cause error: ErrorException: Cannot modify header information – headers already sent by | comment out this function when you run test cases. | test | |
7 | controllers moved into new project are using psr-4. And there are folder structure changes. | need to define namespaces for each controller and use correct namespace for code inside controller. | ||
8 | Can’t set Cookie value | Cookie queuing is not enabled for api requests by default | Add below class in Kernel.php \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | Global |
9 | Rhumsaa\Uuid\Uuid; is deprecated. | use Ramsey\Uuid\Uuid; | Rhumsaa\Uuid\Uuid; | |
10 | Illuminate\Auth\UserTrait; is deprecated. | remove it. use use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; instead. | UserPublicKey model | |
11 | use Illuminate\Database\Eloquent\SoftDeletingTrait; | deprecated. | rename the trait to SoftDeletes. | soft deleting. |
12 | Incorrect datetime value: ‘0000-00-00 00:00:00’ for column ‘created_at’ | mysql’s sql mode settings. | solution options: 1) change the sql_mode to allow zero dates, by removing NO_ZERO_DATE and NO_ZERO_IN_DATE. After a restart of MySQL Server, sql_mode variable will be initialized to the setting in my.cnf. 2) change the created column to allow NULL values, and update the existing rows to change the zero dates to null values UPDATE `users` SET `created` = NULL WHERE `created` = ‘0000-00-00 00:00:00’ 3) update the existing rows to change the zero dates to a valid date UPDATE `users` SET `created` = ‘1970-01-02’ WHERE `created` = ‘0000-00-00 00:00:00’ | tables with timestamp ‘0000-00-00 00:00:00’ as default value. |
13 | lists() is deprecated. | change to use pluck(); Notice: lists() return array, pluck return collections. If want to return array, have to use pluck()->toArray() | models, sql script | |
14 | Error SELECT list is not in GROUP BY clause and contains nonaggregated column … | In database.php, change strict to false (default true) ‘mysql’ => [ …. ‘strict’ => false, | Global database setting | |
15 | eloquent query using first() will not return collection, so count() should not be used. | remove count() | eloquent first() returned result with count() wrapper. | |
16 | pluck() doens’t work properly | in Laravel4.2, pluck() returns the first item of the collection while in laravel 5+, pluck() return an array of the collection | change to pluck()->first() | |
17 | for commands migration, | 1) Tests\Feature\ArtisanComands\ExportAllTest::testExportAllCommand ReflectionException: Method exportAll::handle() does not exist | change fire() (old style) to handle() (new style) | |
18 | UploadedFile::getClientSize is deprecated since Symfony 4.1 | UploadedFile::getClientSize is deprecated since Symfony 4.1 | use getSize() instead. | File upload |
19 | //Debugbar::disable(); is deprecated. | //Debugbar::disable(); is deprecated. | in .env configure APP_DEBUG=true to enable it or false to disable it instead. | web.php |
20 | route file: filter() is deprecated. | route file: filter() is deprecated. | change filter() to middleware() | web.php |
21 | route file: before is deprecated. | route file: before is deprecated. | change before to middleware | web.php |
22 | HTML farcade is abandoned. | HTML and Form is abandoned. | install “laravelcollective/html”: “^6.1”, register HTML and Form as new farcade in appServiceProvider | all views using HTML and Form farcade. |
23 | blade template with content section cannot be rendered. | cannot find $this->layout->content. Controller layout is removed | change template extension to the modern way: 1. @extend(‘layout.default’) 2. return View:make() directly. | all views templates. |
24 | middleware CSRF is replaced by “\App\Http\Middleware\VerifyCsrfToken::class” | middleware CSRF is replaced by “\App\Http\Middleware\VerifyCsrfToken::class” | remove “csrf” middleware. on web.php routes VerifyCsrfToken is enabled by default. | all web.php routes. |
25 | Session::clear() is deprecated. | Session::clear() is deprecated. | use Session::flush() instead. | |
26 | Session::set() is deprecated. | Session::set() is deprecated. | use Session::put() instead. | |
27 | Route::group middleware format is changed. | Route::group middleware format is changed. | use Route::middleware([,])->group() to register middleware on route group. | |
28 | array_except() is deprecated | array_except() is deprecated | e.g use $filtered = Arr::except($array, [‘price’]); instead. | |
29 | Paginator farcade is deprecated. | Paginator farcade is deprecated. | for view composer, use $view->paginator to get the paginator instance. | |
30 | Paginator methods are deprecated. | getLastPage() => lastPage() getCurrentPage() => currentPage() getUrl => url() | getLastPage() => lastPage() getCurrentPage() => currentPage() getUrl => url() | all pagination |
31 | Call to undefined method Symfony\Component\HttpFoundation\BinaryFileResponse::withCookie() | when downloading file, response should not set cookie. | skip $response->withCookie($newCookie); execution. | download file |
31 | setBaseUrl() for paginator is deprecated. | setBaseUrl() for paginator is deprecated. | use withPath() instead | withPath() for pagiantion. |