【過去メモ発掘!】PHP5.6 + Laravel5.1からPHP7.3 + Laravel5.8にアップグレードした時の奮闘メモ

2021-05-07

なにこれ

2年くらい過去のメモが発掘されました。
もうLaravel5.8もサポート外ではあるし、ここまで放置しないため直接は役に立たないが、考え方、やり方は参考になるかもしれないので記録として残すことにします。

行ったアップグレード作業の進め方

  1. 1日でPHP7.3 + Laravel5.8まであげきる。(ローカル環境で)
  2. 更新されていないライブラリを他ライブラリに置き換える
  3. 独自でFW拡張した箇所はLaravel標準機能を利用するように変更する
  4. 更新したコードベースで動作するインスタンスを立てる
  5. テスト
  6. リリース手順作ってレビューしてもらう
  7. リリース

詳細

1. 1日でPHP7.3 + Laravel5.8まであげきる。(ローカル環境で)

なんでこんなことを?

Laravelの5.1から5.8ってマイナーバージョンやん?と思うでしょう。違うのです。。。
Laravelにセマンティックバージョニングが適応されたのは(確か)6系からです。。。
5.1から5.8はメジャーバージョンが7個上がったと捉えてくれるとイメージしやすいかと思います。

メジャーバージョン7個上げるなんていろんなブログ探しても見つからなかったので、どのくらい大変かイメージすらできない状況でした。ビジネスサイドにも稼働時間の説明ができない。
なのでイメージを掴むためにまずは、枝葉を捨ててアップデートをやり切る事で残作業の規模感を把握する方法をとることにした記憶があります。

5.1から5.8へのアップグレードガイドなど存在しないので、地道に5.1→5.2→5.3→…→5.8とアップグレードしていきます。 前提としてある程度クリティカルな箇所にはテストコードが書かれている状況で取り組みました。

とにかくまずは走り切ってみて代替対応や慎重な検討が必要などの項目をリストアップしていきます。

PHP編

ローカル開発環境はdockerイメージの更新で終わり!

と思っていたのですが、いくつか拡張モジュールが死んでいた。。 問題に直面したのは以下の3モジュール

  • mailparse
  • memcached
  • mcrypt

mailparse 過去は利用していたが、機能削除により不要になっていたのでインストールしないように変更。お役目御免。

memcached Redis利用に全部置き換わっているので不要。お役目御免。

mcrypt mcryptはphp7.2からコアモジュールから削除されました。対応方法は2通り。

調査フェーズでは一旦PECLからmcryptをダウンロードした。要検討項目として別途対応とする。

その後の検討メモはこんなの書いていた。

暗号化についてはOpenSSLを利用する。

選定理由
現在のコードはOpenSSLで暗号化している。

Laravelでの暗号化はOpenSSLを利用している。
参考 https://readouble.com/laravel/5.3/ja/encryption.html

mcryptからOpenSSLの移行をする際の参考記事が豊富

参考
https://qiita.com/terra_yucco/items/6fa12af04c86f74089b4
https://qiita.com/sapi_kawahara/items/bbfbc57fd12ff348f216

Laravel編

1日でupdateしてみて検証するためのもの

以下までできたらupdate完了とする

  • composer updateが完了する
  • トップページが表示されるところを確認

超重要な気づき

アップグレードガイドの言っていることがわからない場合はGitHubでLaravelのコードを読みに行く。これ大事。

5.2

アップグレードガイド

https://readouble.com/laravel/5.2/ja/upgrade.html

やってないこと

  • SelfHandlingはいらなくなったらしいが、実装してくと時間かかるのでパス

https://readouble.com/laravel/5.2/ja/upgrade.html#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%90%E3%82%B9%E3%81%A8%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9

ガイドに乗っていない箇所でエラー吐いた箇所

"laravelcollective/html": "5.1.*""laravelcollective/html": "5.2.*"に変更する

5.3

アップグレードガイド

https://readouble.com/laravel/5.3/ja/upgrade.html

やってないこと

ガイドに乗っていない箇所でエラー吐いた箇所

  • "laravelcollective/html": "5.3.*","laravelcollective/html": "5.3.*"に変更する。 以降は全部これでしょう。割愛しますね。
  • App\Libs\Laravel\Queue\QueueServiceProviderという独自のサービスプロバイダの解決行えなかったのでコメントアウト
  • Illuminate\Database\Eloquent\ScopeInterfaceが存在しないよのエラー。コメントアウト。

5.4

アップグレードガイド

https://readouble.com/laravel/5.4/ja/upgrade.html tinkerは絶対いれてください。お願いします。デバッグしやすいねん。

やってないこと

特筆ない

ガイドに乗っていない箇所でエラー吐いた箇所

  • iseedが死んじゃうううう
In IseedServiceProvider.php line 35:
Call to undefined method Illuminate\Foundation\Application::share()  

https://readouble.com/laravel/5.4/ja/upgrade.html#share%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%89%8A%E9%99%A4 share()というメソッドは死にました。

なので以下で対応可能

  • Orangehill\Iseed\IseedServiceProvider::classをコメントアウトする
  • 最新のiseedを入れてcomposer update
  • その後Orangehill\Iseed\IseedServiceProvider::classをコメントから戻して composer update

5.5

アップグレードガイド

https://readouble.com/laravel/5.5/ja/upgrade.html

やってないこと

非互換いろいろあるらしい。なにもしてません。

ガイドに乗っていない箇所でエラー吐いた箇所

  • japanese-holiday/japanese-holidayで依存関係の解決ができない。最新版の2.0.4を試してもダメ。さようなら。日本の祝日

5.6

アップグレードガイド

https://readouble.com/laravel/5.6/ja/upgrade.html

やってないこと

fideloper/proxy依存指定を^4.0へアップデートしてください。 そういうものはcomposer.jsonにありません。

ガイドに乗っていない箇所でエラー吐いた箇所

  • phpspecがあるとsymfonyのverupができない。エラーになる。ので削除しました。phpならXunit系っすよー!!!
  • SHAHashServiceでinfoメソッドを実装する必要あり。Haserという抽象クラスに定義が追加されたため

5.7

アップグレードガイド

https://readouble.com/laravel/5.7/ja/upgrade.html

やってないこと

なんかよみづらい。さらっと見た感じ、対応する箇所少ない。

ガイドに乗っていない箇所でエラー吐いた箇所

  • エラー
> @php artisan package:discover
In Container.php line 960:
Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class Illuminate\Support\Manager                                 

解決方法はhttps://github.com/laravel/framework/issues/26766

5.8

アップグレードガイド

https://readouble.com/laravel/5.8/ja/upgrade.html

やってないこと

なんかよみづらい。composer.json以外なにもやってない

ガイドに乗っていない箇所でエラー吐いた箇所

  • エラー
> @php artisan package:discover
In AirbrakeExceptionHandler.php line 9:                                                                               
Class adamtester\laravelairbrake\Handler\AirbrakeExceptionHandler contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Illuminate\Contracts\Debug\ExceptionHandler::shouldReport)

5.8からIlluminate\Contracts\Debug\ExceptionHandlerにメソッドは1つ追加されてまんがな。 https://laravel.com/api/5.8/Illuminate/Contracts/Debug/ExceptionHandler.html#method_shouldReport

とりあえずvendorのadamtester\laravelairbrake\Handler\AirbrakeExceptionHandlershouldReport(Exception $e)を追記してからcomposer updateをしたら成功した。
この独自で拡張したライブラリにも変更入れる。プルリク作っておきます。

2. 更新されていないライブラリを他ライブラリに置き換える

とりあえず上げ切って対応保留した箇所の整備を行います。 mcryptとかjapanese-holidayとかです。

細かいことは気にせずにアップグレードをやり切って対応リストを作成しておけば、他メンバーにお願いすることも可能になっています。
残りのタスクを見て規模感まではイメージできるようになっています。

最近流行りのライブラリに載せ替えたり、issue巡ったりできるので、結構楽しいフェーズですね。

3. 独自でFW拡張した箇所はLaravel標準機能を利用するように変更する

極力FW提供の機能を活用するように変更してました。
今後のアップデート時にも邪魔になりますし、運がよければFW側で機能拡充してくれますので。

この作業はアップデートを走り抜けた人が担当すると話早いと思います。

4. 更新したコードベースで動作するインスタンスを立てる

当時、EC2ベースで動かしていた背景もあって、既存の開発サーバにデプロイしても動かない状況だったのでEC2で新しいインスタンスを立てました。
一部ECSを活用していたので、その時にコンテナ技術の恩恵を本当に噛み締めました。
この時に全部リプレイスすれば良かったなと心残りです。。。

5. テスト

どこまでやるかは事業特性や組織風土にも関わってくると思うので、その時の状況に応じてください。
当時はユーザ体験を著しく損なうと思われる箇所以外はサクッと確認に留めていました。

6. リリース手順作ってレビューしてもらう

production用のインスタンス作成なり、リリース手順なりをチェックするフェーズです。
残念ながら、このフェーズは自分は新規プロジェクトの方にほぼ付きっきりでそこまで関われず。。。

7. リリース

LBの設定をいじりながら徐々に新サーバに流してバグが発生していないか、サーバメトリクスは問題ないかなどをチェックして、適応範囲を増やしていきました。
旧サーバも切り戻し用に1週間程度は残していた気がします。

おわりに

エンジニア的にはそこそこ面白かったです。
事業としては旨味が少ない割に時間とるので、あんまりかなと。

なので、お互いに共通で関心がある事を主目的で話していた記憶が蘇りました。 セキュリティ攻撃に受けたらすぐには適応できないので事業畳むしかない状態ですよー。とか、アプリがサクサク動くようになるので回遊時間伸びるかもしれませんよー。とか、環境が新しくなるのでエンジニア採用時のマイナスも除去できますよー。とか。

個人的には二度とこのようなバージョンアップをする状況を作りたくないなと思います。終わり。