Laravel5.1から5.5へアップグレード
2017-12-06タイトルの通り、Laravelのバージョンを5.1から5.5へアップグレードしたので、その時のメモです。
ちなみにですが、5.1から5.5へのアップグレードなんてやるべきではないです。新バージョンが出るたびに細かくアップグレードしていくのがベストです。小規模なサービスですら対応範囲は多いので、大規模サービスとなるとかなりの工数がかかると思います。
とりあえずバージョンを上げてみる
5.1から5.5となると変更点はかなりありますが、そこまで大きいプロジェクトでもなかったのでとりあえず5.5にバージョンアップしてみました。
Laravelのバージョンアップは、基本的には composer.json
を書き換えて composer update
を実行します。
composer.json書き換え
まずはcomposer.json
の書き換えとなります。ほぼ全部書き換えです。
とりあえずアップグレード と言ってますが、5.5からはPHPの対応バージョンが7.0以上となっているので、サーバのPHPバージョンが5系のままだと、そもそもアップグレードができません。
今回、PHPのバージョンは7以上だったので、強行突破してます。
diff --git a/composer.json b/composer.json
index cc83e39..14321dd 100644
--- a/composer.json
+++ b/composer.json
@@ -5,15 +5,22 @@
"license": "MIT",
"type": "project",
"require": {
- "php": ">=5.5.9",
- "laravel/framework": "5.1.*",
- "doctrine/dbal": "^2.5"
+ "php": ">=7.0.0",
+ "fideloper/proxy": "~3.3",
+ "laravel/framework": "5.5.*",
+ "laravel/tinker": "~1.0"
},
"require-dev": {
+ "filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
- "phpunit/phpunit": "~4.0",
- "phpspec/phpspec": "~2.1"
+ "phpunit/phpunit": "~6.0"
+ },
+ "extra": {
+ "laravel": {
+ "dont-discover": [
+ ]
+ }
},
"autoload": {
"classmap": [
@@ -31,18 +38,14 @@
},
"scripts": {
"post-root-package-install": [
- "php -r \"copy('.env.example', '.env');\""
+ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
- "php artisan key:generate"
- ],
- "post-install-cmd": [
- "Illuminate\\Foundation\\ComposerScripts::postInstall",
- "php artisan optimize"
+ "@php artisan key:generate"
],
- "post-update-cmd": [
- "Illuminate\\Foundation\\ComposerScripts::postUpdate",
- "php artisan optimize"
+ "post-autoload-dump": [
+ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
+ "@php artisan package:discover"
]
},
"config": {
composer update
composer.json
を書き換えたら、composer update
を実行します。
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
...
...
...
Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
In ProviderRepository.php line 208:
Class 'Illuminate\Routing\ControllerServiceProvider' not found
Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1
これは、5.2へのアップグレード時に対応する内容です。
config/app.php
の中の 下記の記述を削除して、もう一度 composer update
実行。
Illuminate\Routing\ControllerServiceProvider::class,
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
In EventServiceProvider.php line 8:
Declaration of App\Providers\EventServiceProvider::boot(Illuminate\Contract
s\Events\Dispatcher $events) should be compatible with Illuminate\Foundatio
n\Support\Providers\EventServiceProvider::boot()
Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1
またエラーが出ました。
Declaration of App\Providers\EventServiceProvider::boot(Illuminate\Contract
s\Events\Dispatcher $events) should be compatible with Illuminate\Foundatio
n\Support\Providers\EventServiceProvider::boot()
これは、5.3へアップグレードするときの対応内容です。
app/Providers/
以下の EventServiceProvider.php
および RouteServiceProvider.php
の boot()
メソッドの引数を削除します。
@@ -24,9 +24,9 @@ class EventServiceProvider extends ServiceProvider
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
- public function boot(DispatcherContract $events)
+ public function boot()
{
- parent::boot($events);
+ parent::boot();
//
}
@@ -22,11 +22,11 @@ class RouteServiceProvider extends ServiceProvider
* @param \Illuminate\Routing\Router $router
* @return void
*/
- public function boot(Router $router)
+ public function boot()
{
//
- parent::boot($router);
+ parent::boot();
}
/**
再度 composer update
実行。
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Package manifest generated successfully.
成功したようなので、バージョンを確認します。
$ php artisan --version
Laravel Framework 5.5.23
とりあえず動かしてみる
Laravel自体のアップグレードはできたので、プロジェクトのほうを修正していきます。
Laravelの公式ドキュメントは、各バージョンへのアップグレード時に何をする必要があるのかを書いてくれているので、今回のように一気にアップグレードではなく、その都度アップグレードしている場合にはこれに沿って対応してくのが基本です。
- 5.1から5.2 アップグレードガイド 5.2 Laravel
- 5.2から5.3 アップグレードガイド 5.3 Laravel
- 5.3から5.4 アップグレードガイド 5.4 Laravel
- 5.4から5.5 アップグレードガイド 5.5 Laravel
今回は、とりあえず動かしてみて、エラーと戦ってきたいと思います。
セッション
Column not found: 1054 Unknown column 'user_id' in 'field list'
セッションをDBに保持するようにしている場合、上記のようなエラーが出ます。
これは5.2へのアップグレード時に対応する内容で、ドキュメントには次のように書かれています。
ユーザID、IPアドレス、ユーザエージェントのような情報をより含む、新しいdatabaseセッションドライバが書かれました。古いドライバーを使い続けたい場合は、session.php設定ファイルへlegacy-databaseドライバを指定してください。 新しいドライバーを使用する場合、セッションのデータベーステーブルへ、user_id (NULL値を許す整数)、ip_address (NULL値を許す整数)、user_agent (テキスト)カラムを追加してください。
ということで、カラムを追加します。
$ php artisan make:migration alter_add_session
<?php
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('sessions', function($t){
$t->integer('user_id')->nullable();
$t->integer('ip_address')->nullable();
$t->string('user_agent');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('sessions', function($t){
$t->dropColumn(['user_id', 'ip_address', 'user_agent']);
});
}
$ php artisan migrate
**************************************
* Application In Production! *
**************************************
Do you really wish to run this command? (yes/no) [no]:
>
アプリケーションが本番だけど、大丈夫?と聞かれてしまいました。.env
では APP_ENV=local
となっているのに、なぜ?
これも5.2で対応内容ですが、config/app.php
に env
のデフォルトオプションが追加されていました。
diff --git a/config/app.php b/config/app.php
index f013735..3f597f9 100644
--- a/config/app.php
+++ b/config/app.php
@@ -2,6 +2,8 @@
return [
+ 'env' => env('APP_ENV', 'production'),
これで local で確認無しでマイグレーションが通ります。
ルートフィルター
Method [beforeFilter] does not exist on [App\Http\Controllers\***
これは5.1の時点で非推奨、5.2で削除となったルートフィルターの使用によるエラーです。
より好ましいミドルウェアにより、ルートフィルターは非推奨となりました。
とあるように、ミドルウェアへの移行が必要です。まあ、5.1のうちに移行しておくべきだった内容ですが。
ミドルウェアの作成
今回の場合、以下のようにController内にフィルターを書いていました。
<?php
class HogeController extends Controller {
public function __construct()
{
parent::__construct();
$this->beforeFilter("@filterHoge");
}
public function filterHoge()
{
// 処理
}
}
これを、ミドルウェアに移行します。
$ php artisan make:middleware HogeMiddleware
<?php
class HogeMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 処理
return $next($request);
}
}
ヘルパ
url()
url()ヘルパ関数が、引数のパスの指定がない場合にIlluminate\Routing\UrlGeneratorを返すようになりました。
例えばプロジェクトのルートパスが https://hogehoge.com
だった場合、5.1では
<?php
$u = url();
echo $u;
// https://hogehoge.com
でしたが、5.2以降で同じような結果を得るためには
<?php
$u = url('/');
echo $u;
// https://hogehoge.com
とする必要があります。
url()
のまま放置して、その値に文字列結合をしている場合、Object of class Illuminate\Routing\UrlGenerator could not be converted to string
と言われます。
Laravelの恩恵を受けきれていない?
ざっと動かした感じでは致命的なものはこれくらいでした。 おそらく、フレームワークに依存してないのが良かったと思われます。 逆に言うと、Laravelの恩恵を受けきれていないのかもしれません。
何かあれば追記していきます。
comments powered by Disqus