こんにちは、新卒2年目になりました菊池(akikuchi_rks)です。
新卒1年目では開発エンジニアとして様々な経験をさせていただきましたが、その1つとしてLaravel8→9へのバージョンアップ作業を行いました。
今回はこのLaravel9へのバージョンアップにおいて自分が躓いた経験から、注意が必要だと感じた点を紹介させていただきます。
はじめに
Laravel9が2022年2月8日、正式リリースされました。
標準メーラーの変更、Flysystem3.xへのバージョンアップなど様々な変更点がありますが、これらの変更点に関する説明は他の記事で既にまとめられているため本記事では割愛させていただきます。
弊社でも毎月開催している勉強会「PHP TechCafe」において『PHPerのための「Laravel9について語る」』というテーマで議論した回があり、
その内容のレポート記事で、Laravel9の変更点について簡潔にまとめられているので、良ければ参考にしていただければと思います。
Laravelのバージョンアップを行う際は、基本的にLaravel公式のアップグレードガイドでアップグレード手順を確認しながら作業を行うことになると思います。
手動で変更する必要がある修正内容については、ほとんどこちらの公式ドキュメントで説明されているのでこちらを参考に修正を行えば問題ありませんが、私が実際にバージョンアップ作業を行う中で
- 公式ドキュメントに書かれておらず修正が漏れていた
- 公式ドキュメントの説明を正確に理解出来ていなかった
など、いくつか躓いた点がありました。
本記事ではこのような躓いた経験をもとに、注意すべきだと感じた点を紹介させていただきます。
注意すべきこと
依存パッケージの確認
バージョンアップ作業に入る前の話になりますが、アプリケーションの依存パッケージを事前に確認する必要があります。
特に、Laravel9ではSymfony6.x系に依存していますがSymfony6.x系をまだサポートしていないcomposerパッケージが意外とあります。
このような場合は、
- 別のパッケージを使用する
- パッケージを自力でカスタムする
などの対応が必要になります。
Trusted Proxiesファイルの修正
Laravel9へのバージョンアップ対応において、Composerの依存パッケージの変更以外で手作業での修正が必須となるのはこちらの項目くらいだと思います。
そのため、Laravel9へバージョンアップ後にアプリケーションが動かなくなったという場合はまずはこちらの修正が正しく行えているかを確認すると良いと思います。
app/Http/Middleware/TrustProxies.php の修正
変更前
use Fideveloper\Proxy\TrustProxies as Middleware
変更後
use Illuminate\Http\Middleware\TrustProxies as Middleware
$headersの修正
変更前
protected $headers = Request::HEADER_X_FORWARDED_ALL;
変更後
protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_POST | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB ;
因みにTrustProxies.php
以外のファイルでもHEADER_X_FORWARDED_ALL
の定数が使われている場合は修正が必要です。
私の作業を行ったプロジェクトでも他のファイルでHEADER_X_FORWARDED_ALL
が使われていましたが、そのことに気づかず修正が漏れていたことが原因でサービスが動きませんでした。
Storageファサードを利用したファイル操作の仕様変更
Laravel9ではFlysystem 1.x から 3.xへの移行を行っています。
それに伴い、Storageファサードを利用したファイル操作の仕様が一部変わっています。
※参考:Flysystem公式ドキュメント flysystem.thephpleague.com
ファイル書き込み時の仕様
特に注意すべきなのは、write()
、writeStream()
でのファイルの書き込み時の仕様変更です。
Flysystemの公式ドキュメントにも書かれているように、以下の表のように書き込み関連のメソッドの仕様が変更されました。
Flysystem 1.xでは書き込み用のメソッドと更新用のメソッドが別で用意されており、write()
が上書き処理をすることはありませんでした。
また、書き込みと更新を自動で使い分けてくれるメソッドとしてput()
が用意されていました。
Flysystem 3.xでは以前のput()
の機能をwrite()
が担うようになり、wirte()
とupdate()
は削除されました。
この仕様変更に伴い、Laravel9のStorageファサードでput()やwrite()を使用した際は、どちらもFlysystemのwrite()
が呼び出され、自動的に既存ファイルを上書きするようになりました。
もし、既存のファイルを上書きしたくない場合は、手動でファイルの存在確認をする必要があります。
この対応を怠ると、意図せず既存ファイルを上書きしてしまう、という事象が発生してしまうため注意が必要です。
略語を使用したメソッド名の変更
こちらはLaravel公式のアップグレードガイドに載っていない内容ですが、該当のメソッドを使用している場合は対応が必要です。
Flysystem 1.x から 3.xへの移行の影響で省略された単語を含むメソッド名が省略なしの単語を使ったメソッド名に変更されました。
LaravelではIlluminate\Filesystem\FilesystemAdapter.php
に定義されていないメソッドをStorageファサードで呼び出した際、Flysystemのメソッドを直接呼び出す仕組みがありますが、
この仕組みを利用して、今回変更があったメソッドを直接呼び出している場合は、変更後のメソッド名に修正する必要があります。
以下が変更されたメソッド名の例です。
変更前
$filesystem->createDir($path); $filesystem->deleteDir($path);
変更後
$filesystem->createDirectory($path); $filesystem->deleteDirectory($path);
Unvalidated Array Keysの仕様変更
配列に対してバリデーションを行った際の挙動が変わりました。
具体的にはLaravelのバリデータが返すバリデーション済みデータにバリデーションしていない配列キーを含むかどうかが変わっています。
このあたりの仕様変更については、ドキュメントを読んだだけではいまいちピンと来なかったため、具体例を用いて説明しようと思います。
例えば'staff' => ['name' => '田中太郎', 'age' => 26]
のような配列のバリデーションをする場合を考えてみます。
<?php // ①バリデーションしていない配列キーを含む設定がされている場合 $validated = $request->validate([ 'staff' => ['array'], 'staff.name' => ['string'], ]); var_dump($validated); // array(1) { // ['staff']=> // array(2) { // ["name"]=> // string(12) "田中太郎" // ["age"]=> // int(23) // } //} // ②バリデーションしていない配列キーを除外する設定がされている場合 $validated = $request->validate([ 'staff' => ['array'], 'staff.name' => ['string'], ]); var_dump($validated); // array(1) { // ['staff']=> // array(1) { // ["name"]=> // string(12) "田中太郎" // } //}
上記の例のように配列の特定のキーに対してバリデーションを行わなかった場合に、validate()
で返されるデータがそのキーを含むかどうかに違いがあります。
以前のリリースのLaravelではデフォルトで①、アプリケーションのサービスプロバイダのboot()
内でexcludeUnvalidatedArrayKeys()
を呼び出している場合は②の挙動となる仕様でした。
一方で、Laravel9ではデフォルトで②、アプリケーションのサービスプロバイダのboot()
内でincludeUnvalidatedArrayKeys()
を呼び出している場合は①の挙動となる仕様に変更されています。
そのため、推奨はされていませんが、以前のリリースの動作を保つためにはincludeUnvalidatedArrayKeys()
を呼び出す必要があります。
因みに、配列の要素に対してバリデーションを全く設定していない場合は②のようなバリデーションしていない配列キーを除外する設定にしていても、validate()
で返されるデータに全てのキーが含まれる挙動になっているようなので注意が必要です。
<?php $validated = $request->validate([ 'staff' => ['array'], ]); var_dump($validated); // array(1) { // ['staff']=> // array(2) { // ["name"]=> // string(12) "田中太郎" // ["age"]=> // int(23) // } //}
終わりに
今回は、Laravel8からLaravel9へバージョンアップ作業を行う際の注意点について紹介させていただきました。
Laravel9は残念ながらLTSではなくなったので、Laravel10へのバージョンアップ作業も早々に取り組む必要がありそうですね、、
Laravel10へのバージョンアップを行う際は、今回の経験を生かしてよりスムーズに作業を終えられるよう頑張りたいです。
以上です。 本記事が少しでもLaravelバージョンアップ時の手助けになれば嬉しいです。