Readouble

Laravel 9.x アップグレードガイド

重要度の高い変更High Impact Changes

重要度が中程度の変更Medium Impact Changes

8.xから9.0へのアップグレードUpgrading To 9.0 From 8.x

アップグレード時間の見積もり:30分Estimated Upgrade Time: 30 Minutes

lightbulb Note:私たちは、互換性のない変更を可能な限りすべて文書化するよう努力しています。これらの互換性のない変更の一部はフレームワークの不明瞭な部分であり、こうした変更の一部が実際にあなたのアプリケーションに影響を与える可能性があります。時間を節約したいですか?Laravel Shift を使用すると、アプリケーションのアップグレードを自動化できます。Note
We attempt to document every possible breaking change. Since some of these breaking changes are in obscure parts of the framework only a portion of these changes may actually affect your application. Want to save time? You can use Laravel Shift[https://laravelshift.com/] to help automate your application upgrades.

依存パッケージのアップデートUpdating Dependencies

影響の可能性: 高いLikelihood Of Impact: High

PHP8.0.2が必要PHP 8.0.2 Required

今回より、Laravelを動作させるには、PHP8.0.2以上が必要になりました。Laravel now requires PHP 8.0.2 or greater.

Composerの依存パッケージComposer Dependencies

アプリケーションのcomposer.jsonファイルにある、以下の依存パッケージを更新してください。You should update the following dependencies in your application's composer.json file:

  • laravel/framework^9.0に変更laravel/framework to ^9.0
  • nunomaduro/collision^6.1に変更nunomaduro/collision to ^6.1

さらに、アプリケーションのcomposer.jsonファイル中の、facade/ignition"spatie/laravel-ignition": "^1.0"へ置き換え、(該当する場合は)pusher/pusher-php-server"pusher/pusher-php-server": "^5.0"へ置き換えてください。In addition, please replace facade/ignition with "spatie/laravel-ignition": "^1.0" and pusher/pusher-php-server (if applicable) with "pusher/pusher-php-server": "^5.0" in your application's composer.json file.

さらに、以下のファーストパーティパッケージは、Laravel9.x をサポートするために新しくメジャーリリースしました。当てはまる場合、Laravelをアップグレードする前に、それぞれのアップグレードガイドを読んでください。Furthermore, the following first-party packages have received new major releases to support Laravel 9.x. If applicable, you should read their individual upgrade guides before upgrading:

最後に、アプリケーションで使用している他のサードパーティパッケージを調べ、Laravel9をサポートする適切なバージョンを使用していることを確認してください。Finally, examine any other third-party packages consumed by your application and verify you are using the proper version for Laravel 9 support.

PHPの戻り値タイプPHP Return Types

PHPでは、offsetGetoffsetSetなどのPHPメソッドへ、戻り値のタイプの定義を義務付ける方向に移行し始めています。これを踏まえ、Laravel9ではコードベースにこれらの戻り値の型を実装しています。通常、ユーザーが書いたコードには影響しませんが、Laravelのコアクラスを拡張してこれらのメソッドをオーバーライドしている場合は、これらの戻り値の型を自分のアプリケーションやパッケージのコードに追加することが必要になります。PHP is beginning to transition to requiring return type definitions on PHP methods such as offsetGet, offsetSet, etc. In light of this, Laravel 9 has implemented these return types in its code base. Typically, this should not affect user written code; however, if you are overriding one of these methods by extending Laravel's core classes, you will need to add these return types to your own application or package code:

  • count(): intcount(): int
  • getIterator(): TraversablegetIterator(): Traversable
  • getSize(): intgetSize(): int
  • jsonSerialize(): arrayjsonSerialize(): array
  • offsetExists($key): booloffsetExists($key): bool
  • offsetGet($key): mixedoffsetGet($key): mixed
  • offsetSet($key, $value): voidoffsetSet($key, $value): void
  • offsetUnset($key): voidoffsetUnset($key): void

さらに、PHPのSessionHandlerInterfaceを実装したメソッドに戻り値のタイプが追加されました。繰り返しますが、この変更があなた自身のアプリケーションやパッケージのコードに、影響を与えることはまずないでしょう。In addition, return types were added to methods implementing PHP's SessionHandlerInterface. Again, it is unlikely that this change affects your own application or package code:

  • open($savePath, $sessionName): boolopen($savePath, $sessionName): bool
  • close(): boolclose(): bool
  • read($sessionId): string|falseread($sessionId): string|false
  • write($sessionId, $data): boolwrite($sessionId, $data): bool
  • destroy($sessionId): booldestroy($sessionId): bool
  • gc($lifetime): intgc($lifetime): int

アプリケーションApplication

Application契約The Application Contract

影響の可能性: 低いLikelihood Of Impact: Low

Illuminate\Contracts\Foundation\ApplicationインターフェイスのstoragePathメソッドを更新し、$path引数を取るようにしました。このインターフェイスを実装している場合、それに応じて実装を更新する必要があります。The storagePath method of the Illuminate\Contracts\Foundation\Application interface has been updated to accept a $path argument. If you are implementing this interface you should update your implementation accordingly:

public function storagePath($path = '');

同様に、Illuminate\Foundation\ApplicationクラスのlangPathメソッドを更新し、$path引数を取るようになりました。Similarly, the langPath method of the Illuminate\Foundation\Application class has been updated to accept a $path argument:

public function langPath($path = '');

例外ハンドラのignoreメソッドException Handler ignore Method

影響の可能性: 低いLikelihood Of Impact: Low

例外ハンドラのignoreメソッドが、protectedからpublicへ変更しました。このメソッドはデフォルトのアプリケーションスケルトンには含まれていません。しかし、もしこのメソッドを独自に定義している場合は、可視性をpublicへ更新する必要があります。The exception handler's ignore method is now public instead of protected. This method is not included in the default application skeleton; however, if you have manually defined this method you should update its visibility to public:

public function ignore(string $class);

例外ハンドラ契約の依存結合Exception Handler Contract Binding

影響の可能性: かなり低いLikelihood Of Impact: Very Low

以前、Laravelのデフォルト例外ハンドラをオーバーライドするには、\App\Exceptions\Handler::classタイプのカスタム実装を使い、サービスコンテナへ依存結合していました。しかし今後は、\Illuminate\Contracts\Debug\ExceptionHandler::classタイプを使用して依存結合する必要があります。Previously, in order to override the default Laravel exception handler, custom implementations were bound into the service container using the \App\Exceptions\Handler::class type. However, you should now bind custom implementations using the \Illuminate\Contracts\Debug\ExceptionHandler::class type.

BladeBlade

レイジーコレクションと$loop変数Lazy Collections & The $loop Variable

影響の可能性: 低いLikelihood Of Impact: Low

Bladeテンプレート内のLazyCollectionインスタンスを反復処理すると$loop変数は使用できなくなります。この変数にアクセスすると、LazyCollection全体がメモリに読み込まれるため、このシナリオではレイジーコレクションの使用が無意味になるためです。When iterating over a LazyCollection instance within a Blade template, the $loop variable is no longer available, as accessing this variable causes the entire LazyCollection to be loaded into memory, thus rendering the usage of lazy collections pointless in this scenario.

Checked/Disabled/Selected BladeディレクティブChecked / Disabled / Selected Blade Directives

影響の可能性: 低いLikelihood Of Impact: Low

新しい@checked@disabled@selected Bladeディレクティブは、同名のVueイベントと競合する可能性があります。@@でディレクティブをエスケープすると、この衝突を回避できます。The new @checked, @disabled, and @selected Blade directives may conflict with Vue events of the same name. You may use @@ to escape the directives and avoid this conflict: @@selected.

コレクションCollections

Enumerable契約The Enumerable Contract

影響の可能性: 低いLikelihood Of Impact: Low

Illuminate\Support\Enumerable契約に、soleメソッドを定義しました。このインターフェイスを実装している場合は、この新しいメソッドを反映するよう実装を更新してください。The Illuminate\Support\Enumerable contract now defines a sole method. If you are manually implementing this interface, you should update your implementation to reflect this new method:

public function sole($key = null, $operator = null, $value = null);

reduceWithKeysメソッドThe reduceWithKeys Method

reduceメソッドが同じ機能を提供しているため、reduceWithKeysメソッドを削除しました。reduceWithKeysの代わりに、reduceを呼び出すようにコードを更新するだけです。The reduceWithKeys method has been removed as the reduce method provides the same functionality. You may simply update your code to call reduce instead of reduceWithKeys.

reduceManyメソッドThe reduceMany Method

reduceManyメソッドは、他の同様のメソッドと名前の一貫性を保つため、reduceSpreadへ名前を変更しました。The reduceMany method has been renamed to reduceSpread for naming consistency with other similar methods.

コンテナContainer

Container契約The Container Contract

影響の可能性: とても低いLikelihood Of Impact: Very Low

Illuminate\Contracts\Container\Container契約は、scopedscopedIfの2メソッド定義を受けるようにしました。この契約を実装している場合は、これらの新しいメソッドを反映するように実装を更新してください。The Illuminate\Contracts\Container\Container contract has received two method definitions: scoped and scopedIf. If you are manually implementing this contract, you should update your implementation to reflect these new methods.

ContextualBindingBuilder契約The ContextualBindingBuilder Contract

影響の可能性: とても低いLikelihood Of Impact: Very Low

Illuminate\Contracts\Container\ContextualBindingBuilder契約で、giveConfigメソッドを定義しました。このインターフェイスを実装している場合は、この新しいメソッドを反映するように更新してください。The Illuminate\Contracts\Container\ContextualBindingBuilder contract now defines a giveConfig method. If you are manually implementing this interface, you should update your implementation to reflect this new method:

public function giveConfig($key, $default = null);

データベースDatabase

Postgres "Schema"設定Postgres "Schema" Configuration

影響の可能性: 中程度Likelihood Of Impact: Medium

アプリケーションのconfig/database.php設定ファイルで、Postgres接続検索パスを設定するために使用するschema設定オプションの名前をsearch_pathへ変更してください。The schema configuration option used to configure Postgres connection search paths in your application's config/database.php configuration file should be renamed to search_path.

Schema Builder registerCustomDoctrineType MethodSchema Builder registerCustomDoctrineType Method

影響の可能性: 低いLikelihood Of Impact: Low

registerCustomDoctrineTypeメソッドは、Illuminate\Database\Schema\Builderクラスから削除しました。代わりに、DBファサードで、registerDoctrineTypeメソッドを使用するか、config/database.php設定ァイルで、カスタムDoctrineタイプを登録できます。The registerCustomDoctrineType method has been removed from the Illuminate\Database\Schema\Builder class. You may use the registerDoctrineType method on the DB facade instead, or register custom Doctrine types in the config/database.php configuration file.

EloquentEloquent

カスタムキャストとnullCustom Casts & null

影響の可能性: 中程度Likelihood Of Impact: Medium

Laravel の以前のリリースでは、カスタムキャストクラスのsetメソッドは、キャスト属性がnullに設定されている場合には呼び出しませんでした。しかし、この動作はLaravelのドキュメントと矛盾していました。Laravel9.xでは、キャストクラスのsetメソッドは$value引数にnullを指定しても起動されます。したがって、カスタムキャストがこのシナリオを確実に処理できるようにしてください。In previous releases of Laravel, the set method of custom cast classes was not invoked if the cast attribute was being set to null. However, this behavior was inconsistent with the Laravel documentation. In Laravel 9.x, the set method of the cast class will be invoked with null as the provided $value argument. Therefore, you should ensure your custom casts are able to sufficiently handle this scenario:

/**
 * 指定値を保存のために準備
 *
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @param  string  $key
 * @param  AddressModel  $value
 * @param  array  $attributes
 * @return array
 */
public function set($model, $key, $value, $attributes)
{
    if (! $value instanceof AddressModel) {
        throw new InvalidArgumentException('The given value is not an Address instance.');
    }

    return [
        'address_line_one' => $value->lineOne,
        'address_line_two' => $value->lineTwo,
    ];
}

Belongs To ManyのfirstOrNewfirstOrCreateupdateOrCreateメソッドBelongs To Many firstOrNew, firstOrCreate, and updateOrCreate Methods

影響の可能性: 中程度Likelihood Of Impact: Medium

belongsToManyリレーションシップのfirstOrNewfirstOrCreateupdateOrCreateメソッドの最初の引数に、属性の配列が渡されます。Laravelの以前のリリースでは、この属性の配列は、既存のレコードの「ピボット」/中間テーブルと比較されていました。The belongsToMany relationship's firstOrNew, firstOrCreate, and updateOrCreate methods all accept an array of attributes as their first argument. In previous releases of Laravel, this array of attributes was compared against the "pivot" / intermediate table for existing records.

しかし、この動作は期待されておらず、一般的に望まれないものでした。代わりに、これらのメソッドは関連モデルのテーブルに対して属性の配列を比較するようになりました。However, this behavior was unexpected and typically unwanted. Instead, these methods now compare the array of attributes against the table of the related model:

$user->roles()->updateOrCreate([
    'name' => 'Administrator',
]);

さらに、firstOrCreateメソッドの第2引数に、$values配列を取るようになりました。この配列は、関連モデルが存在していない場合に、メソッドの第1引数($attributes)へマージします。この変更により、このメソッドは他のリレーションタイプで提供しているfirstOrCreateメソッドと動作が一致するようになりました。In addition, the firstOrCreate method now accepts a $values array as its second argument. This array will be merged with the first argument to the method ($attributes) when creating the related model if one does not already exist. This change makes this method consistent with the firstOrCreate methods offered by other relationship types:

$user->roles()->firstOrCreate([
    'name' => 'Administrator',
], [
    'created_by' => $user->id,
]);

touchメソッドThe touch Method

影響の可能性: 低いLikelihood Of Impact: Low

touchメソッドへ、属性を指定できるようになりました。以前このメソッドを上書きしていた場合は、この新しい引数を反映させるためにメソッドの引数指定を変更してください。The touch method now accepts an attribute to touch. If you were previously overwriting this method, you should update your method signature to reflect this new argument:

public function touch($attribute = null);

暗号化Encryption

Encrypter契約The Encrypter Contract

影響の可能性: 低いLikelihood Of Impact: Low

Illuminate\Contracts\Encryption\Encrypter契約で、getKeyメソッドを定義しました。このインターフェイスを実装している場合は、それに応じて更新してください。The Illuminate\Contracts\Encryption\Encrypter contract now defines a getKey method. If you are manually implementing this interface, you should update your implementation accordingly:

public function getKey();

ファサードFacades

getFacadeAccessorメソッドThe getFacadeAccessor Method

影響の可能性: 低いLikelihood Of Impact: Low

getFacadeAccessorメソッドは常にコンテナ結合キーを返す必要があります。Laravelの以前のリリースでは、このメソッドはオブジェクトのインスタンスを返すことができましたが、この動作はもうサポートしません。独自のファサードを記述している場合は、このメソッドがコンテナ結合文字列を返すようにしなければなりません。The getFacadeAccessor method must always return a container binding key. In previous releases of Laravel, this method could return an object instance; however, this behavior is no longer supported. If you have written your own facades, you should ensure that this method returns a container binding string:

/**
 * コンポーネントの登録名取得
 *
 * @return string
 */
protected static function getFacadeAccessor()
{
    return Example::class;
}

ファイルシステムFilesystem

FILESYSTEM_DRIVER環境変数The FILESYSTEM_DRIVER Environment Variable

影響の可能性: 低いLikelihood Of Impact: Low

FILESYSTEM_DRIVER環境変数は、より正確にその使用目的を反映するため、FILESYSTEM_DISKへ名前を変更しました。この変更はアプリケーションのスケルトンにしか影響しませんが、もし望むなら、あなた自身のアプリケーションの環境変数を更新し、この変更を反映させてもかまいません。The FILESYSTEM_DRIVER environment variable has been renamed to FILESYSTEM_DISK to more accurately reflect its usage. This change only affects the application skeleton; however, you are welcome to update your own application's environment variables to reflect this change if you wish.

"Cloud"ディスクThe "Cloud" Disk

影響の可能性: 低いLikelihood Of Impact: Low

ディスク設定オプションのcloudは、2020年11月にデフォルトのアプリケーションスケルトンから削除しました。この変更は、アプリケーションのスケルトンにのみ影響します。アプリケーション内でcloudディスクを使用している場合は、この設定値を自分のアプリケーションのスケルトンに残しておく必要があります。The cloud disk configuration option was removed from the default application skeleton in November of 2020. This change only affects the application skeleton. If you are using the cloud disk within your application, you should leave this configuration value in your own application's skeleton.

Flysystem 3.xFlysystem 3.x

影響の可能性: 高いLikelihood Of Impact: High

Laravel9.xは、Flysystem1.xから3.xへ移行しました。Flysystem は、Storageファサードが提供するすべてのファイル操作メソッドを裏で提供しています。これにより、あなたのアプリケーションでいくらかの変更が必要になるかもしれません。しかし、私たちはこの移行を可能な限りシームレスに行えるように努めました。Laravel 9.x has migrated from Flysystem[https://flysystem.thephpleague.com/v2/docs/] 1.x to 3.x. Under the hood, Flysystem powers all of the file manipulation methods provided by the Storage facade. In light of this, some changes may be required within your application; however, we have tried to make this transition as seamless as possible.

ドライバ要件Driver Prerequisites

S3、FTP、SFTPドライバを使用する前に、Composerパッケージマネージャで適切なパッケージをインストールする必要があります。Before using the S3, FTP, or SFTP drivers, you will need to install the appropriate package via the Composer package manager:

  • Amazon S3: composer require -W league/flysystem-aws-s3-v3 "^3.0"Amazon S3: composer require -W league/flysystem-aws-s3-v3 "^3.0"
  • FTP: composer require league/flysystem-ftp "^3.0"FTP: composer require league/flysystem-ftp "^3.0"
  • SFTP: composer require league/flysystem-sftp-v3 "^3.0"SFTP: composer require league/flysystem-sftp-v3 "^3.0"

既存ファイルの上書きOverwriting Existing Files

putwritewriteStreamなどの書き込み操作は、デフォルトで既存のファイルを上書きするようになりました。既存のファイルを上書きしたくない場合は、書き込み操作を行う前に、ファイルの存在を確認してください。Write operations such as put, write, and writeStream now overwrite existing files by default. If you do not want to overwrite existing files, you should manually check for the file's existence before performing the write operation.

Writeの例外Write Exceptions

putwritewriteStreamなど書き込み操作で、書き込みに失敗しても例外を投げなくなりました。代わりに、falseを返します。例外を投げる以前の動作を維持する場合は、ファイルシステムのディスク設定配列で、throwオプションを定義してください。Write operations such as put, write, and writeStream no longer throw an exception when a write operation fails. Instead, false is returned. If you would like to preserve the previous behavior which threw exceptions, you may define the throw option within a filesystem disk's configuration array:

'public' => [
    'driver' => 'local',
    // ...
    'throw' => true,
],

存在しないファイルからの読み込みReading Missing Files

存在しないファイルから読み込もうとすると、nullを返すようにしました。以前のLaravelのリリースでは、Illuminate\Contracts\Filesystem\FileNotFoundExceptionを投げていました。Attempting to read from a file that does not exist now returns null. In previous releases of Laravel, an Illuminate\Contracts\Filesystem\FileNotFoundException would have been thrown.

存在しないファイルの削除Deleting Missing Files

存在しないファイルをdeleteしようとすると、trueを返すようにしました。Attempting to delete a file that does not exist now returns true.

キャッシュ済みアダプタCached Adapters

Flysystemは、「キャッシュ済みアダプタ」をサポートしなくなりました。そのため、Laravel から削除し、関連する設定(ディスク設定内のcacheキーなど)もすべて削除しました。Flysystem no longer supports "cached adapters". Thus, they have been removed from Laravel and any relevant configuration (such as the cache key within disk configurations) can be removed.

カスタムファイルシステムCustom Filesystems

カスタムファイルシステムドライバの登録に必要な手順が若干変更されました。したがって、もしあなたが独自のカスタムファイルシステムドライバを定義していたり、カスタムドライバを定義しているパッケージを使用していた場合は、あなたのコードと依存を更新する必要があります。Slight changes have been made to the steps required to register custom filesystem drivers. Therefore, if you were defining your own custom filesystem drivers, or using packages that define custom drivers, you should update your code and dependencies.

たとえば、Laravel8.xのカスタムファイルシステムの登録は、以下のようでした。For example, in Laravel 8.x, a custom filesystem driver might be registered like so:

use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

Storage::extend('dropbox', function ($app, $config) {
    $client = new DropboxClient(
        $config['authorization_token']
    );

    return new Filesystem(new DropboxAdapter($client));
});

しかし、Laravel9.xから、Storage::extendメソッドへ与えられるコールバックは、直接Illuminate\Filesystem\FilesystemAdapterインスタンスを返さなければなりません。However, in Laravel 9.x, the callback given to the Storage::extend method should return an instance of Illuminate\Filesystem\FilesystemAdapter directly:

use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

Storage::extend('dropbox', function ($app, $config) {
    $adapter = new DropboxAdapter(
        new DropboxClient($config['authorization_token'])
    );

    return new FilesystemAdapter(
        new Filesystem($adapter, $config),
        $adapter,
        $config
    );
});

ヘルパHelpers

data_getヘルパとIterableオブジェクトThe data_get Helper & Iterable Objects

影響の可能性: とても低いLikelihood Of Impact: Very Low

以前は、data_getヘルパを使用して、配列およびCollectionインスタンスのネストされたデータを取得できました。しかし今、このヘルパは、すべての反復可能なオブジェクトのネストされたデータを取得するようになりました。Previously, the data_get helper could be used to retrieve nested data on arrays and Collection instances; however, this helper can now retrieve nested data on all iterable objects.

strヘルパThe str Helper

影響の可能性: とても低いLikelihood Of Impact: Very Low

Laravel9.xでは、グローバルなstrヘルパ関数を取り入れました。アプリケーションでグローバルなstrヘルパを定義している場合は、Laravel自身のstrヘルパと競合しないように、名前を変更するか削除する必要があります。Laravel 9.x now includes a global str helper function[/docs/{{version}}/helpers#method-str]. If you are defining a global str helper in your application, you should rename or remove it so that it does not conflict with Laravel's own str helper.

whenunlessメソッドThe when / unless Methods

影響の可能性: 中程度Likelihood Of Impact: Medium

お気づきでしょうが、whenメソッドとunlessメソッドは、フレームワーク全体のさまざまなクラスで提供しています。これらのメソッドは、メソッドの最初の引数のブール値がtrue、またはfalseと評価された場合、条件付きでアクションを実行するために使用します。As you may know, when and unless methods are offered by various classes throughout the framework. These methods can be used to conditionally perform an action if the boolean value of the first argument to the method evaluates to true or false:

$collection->when(true, function ($collection) {
    $collection->merge([1, 2, 3]);
});

そのため、以前のLaravelのリリースでは、whenまたはunlessメソッドにクロージャを渡すとは、クロージャオブジェクト(または他のオブジェクト)に対し緩い比較が行われるため、常に結果はtrueに評価され、条件付き操作が常に実行されることを意味しました。これはしばしば、予想外の結果を生みました。なぜなら、開発者はクロージャの 結果 が、条件付きアクションが実行されるかどうかを決定するブール値として使用されることを期待していたからです。Therefore, in previous releases of Laravel, passing a closure to the when or unless methods meant that the conditional operation would always execute, since a loose comparison against a closure object (or any other object) always evaluates to true. This often led to unexpected outcomes because developers expect the result of the closure to be used as the boolean value that determines if the conditional action executes.

そのため、Laravel9.xではwhenunlessメソッドに渡されたクロージャは実行され、クロージャが返す値がwhenunlessメソッドが使う理論値とみなすようにしました。So, in Laravel 9.x, any closures passed to the when or unless methods will be executed and the value returned by the closure will be considered the boolean value used by the when and unless methods:

$collection->when(function ($collection) {
    // このクロージャは実行される
    return false;
}, function ($collection) {
    // クロージャが"false"を返しているため、実行されない
    $collection->merge([1, 2, 3]);
});

HTTPクライアントHTTP Client

デフォルトタイムアウトDefault Timeout

影響の可能性: 中程度Likelihood Of Impact: Medium

HTTPクライアントのデフォルトのタイムアウトを30秒にしました。つまり、30秒以内にサーバから応答がない場合、例外が発生するようになります。以前は、HTTPクライアントにデフォルトのタイムアウトの長さが設定されていなかったため、リクエストが永久に「ハングアップ」することがありました。The HTTP client[/docs/{{version}}/http-client] now has a default timeout of 30 seconds. In other words, if the server does not respond within 30 seconds, an exception will be thrown. Previously, no default timeout length was configured on the HTTP client, causing requests to sometimes "hang" indefinitely.

もし、指定するリクエストへより長いタイムアウトを指定したい場合は、timeoutメソッドを使用して指定できます。If you wish to specify a longer timeout for a given request, you may do so using the timeout method:

$response = Http::timeout(120)->get(/* ... */);

HTTP FakeとミドルウェアHTTP Fake & Middleware

影響の可能性: 低いLikelihood Of Impact: Low

以前は、HTTPクライアントが "fake"されていても、Laravelは指定されたGuzzle HTTPミドルウェアを実行しませんでした。しかし、Laravel 9.xでは、HTTPクライアントがFakeであっても、Guzzle HTTPミドルウェアは実行されます。Previously, Laravel would not execute any provided Guzzle HTTP middleware when the HTTP client[/docs/{{version}}/http-client] was "faked". However, in Laravel 9.x, Guzzle HTTP middleware will be executed even when the HTTP client is faked.

HTTP Fakeと依存注入HTTP Fake & Dependency Injection

影響の可能性: 低いLikelihood Of Impact: Low

Laravelの以前のリリースでは、Http::fake()メソッドを起動しても、クラスコンストラクタへ注入されたIlluminate\Http\Client\Factoryインスタンスに影響を与えませんでした。しかし、Laravel9.xでは、Http::fake()は、依存注入により他のサービスへ注入されたHTTPクライアントがFakeレスポンスを返すことを保証します。この動作は、他のファサードやFakeの動作とより一貫性があります。In previous releases of Laravel, invoking the Http::fake() method would not affect instances of the Illuminate\Http\Client\Factory that were injected into class constructors. However, in Laravel 9.x, Http::fake() will ensure fake responses are returned by HTTP clients injected into other services via dependency injection. This behavior is more consistent with the behavior of other facades and fakes.

Symfony MailerSymfony Mailer

影響の可能性: 高いLikelihood Of Impact: High

Laravl9.xの最大の変更点は、2021年12月をもってメンテナンスが終了したSwiftMailerから、Symfony Mailerへの移行したことです。しかし、私たちはあなたのアプリケーションで、この移行ができるだけシームレスになるように努めました。とはいえ、あなたのアプリケーションで完全に互換を保てるように、以下の変更点のリストを十分に確認してください。One of the largest changes in Laravel 9.x is the transition from SwiftMailer, which is no longer maintained as of December 2021, to Symfony Mailer. However, we have tried to make this transition as seamless as possible for your applications. That being said, please thoroughly review the list of changes below to ensure your application is fully compatible.

ドライバ要求Driver Prerequisites

Mailgunトランスポートを引き続き使用するには、symfony/mailgun-mailersymfony/http-client Composerパッケージがアプリケーションに必要です。To continue using the Mailgun transport, your application should require the symfony/mailgun-mailer and symfony/http-client Composer packages:

composer require symfony/mailgun-mailer symfony/http-client

wildbit/swiftmailer-postmark Composerパッケージをアプリケーションから削除する必要があります。代わりに、symfony/postmark-mailersymfony/http-client Composerパッケージが必要です。The wildbit/swiftmailer-postmark Composer package should be removed from your application. Instead, your application should require the symfony/postmark-mailer and symfony/http-client Composer packages:

composer require symfony/postmark-mailer symfony/http-client

戻り値の変更Updated Return Types

Illuminate\Mail\Mailersend htmltextplainメソッドは、voidを返さなくしました。代わりに、Illuminate\Mail\SentMessageインスタンスを返します。このオブジェクトには、getSymfonySentMessageメソッドでアクセス、もしくはオブジェクトのメソッドを動的に呼び出すことでアクセスできるSymfony\Component\Mailer\SentMessageインスタンスが含まれています。The send, html, raw, and plain methods on Illuminate\Mail\Mailer no longer return void. Instead, an instance of Illuminate\Mail\SentMessage is returned. This object contains an instance of Symfony\Component\Mailer\SentMessage that is accessible via the getSymfonySentMessage method or by dynamically invoking methods on the object.

"Swift"メソッドの変更Renamed "Swift" Methods

一部は文書化されていない、さまざまなSwiftMailer関連のメソッドは、Symfony Mailerの対応するメソッドへ名前を変更しました。たとえば、withSwiftMessageメソッドの名前をwithSymfonyMessageに変更しました。Various SwiftMailer related methods, some of which were undocumented, have been renamed to their Symfony Mailer counterparts. For example, the withSwiftMessage method has been renamed to withSymfonyMessage:

// Laravel8.x
$this->withSwiftMessage(function ($message) {
    $message->getHeaders()->addTextHeader(
        'Custom-Header', 'Header Value'
    );
});

// Laravel9.x
use Symfony\Component\Mime\Email;

$this->withSymfonyMessage(function (Email $message) {
    $message->getHeaders()->addTextHeader(
        'Custom-Header', 'Header Value'
    );
});

warning Warning! Symfony\Component\Mime\Emailオブジェクトと関わるすべてに関して、Symfony Mailerドキュメントを徹底的に確認してください。Warning
Please thoroughly review the Symfony Mailer documentation[https://symfony.com/doc/6.0/mailer.html#creating-sending-messages] for all possible interactions with the Symfony\Component\Mime\Email object.

以下のリストには、改名されたメソッドの概要がより詳細に記載されています。これらのメソッドの多くは SwiftMailer/Symfony Mailer と直接やりとりするための低レベルのメソッドなので、ほとんどの Laravel アプリケーションの中で一般的に使われることはないと思われます。The list below contains a more thorough overview of renamed methods. Many of these methods are low-level methods used to interact with SwiftMailer / Symfony Mailer directly, so may not be commonly used within most Laravel applications:

Message::getSwiftMessage();
Message::getSymfonyMessage();

Mailable::withSwiftMessage($callback);
Mailable::withSymfonyMessage($callback);

MailMessage::withSwiftMessage($callback);
MailMessage::withSymfonyMessage($callback);

Mailer::getSwiftMailer();
Mailer::getSymfonyTransport();

Mailer::setSwiftMailer($swift);
Mailer::setSymfonyTransport(TransportInterface $transport);

MailManager::createTransport($config);
MailManager::createSymfonyTransport($config);

Illuminate\Mail\Messageメソッドのプロキシ処理Proxied Illuminate\Mail\Message Methods

Illuminate\Mail\Messageは通常、見つからないメソッドを裏で動作しているSwift_Messageインスタンスへプロキシしていました。しかし、見つからないメソッドは、代わりにSymfony\Component\Mime\Emailインスタンスへプロキシするようにしました。したがって、これまで見つからないメソッドがSwiftMailerへプロキシされる動作に依存していたコードは、対応するsymfony Mailerのメソッドへ更新する必要があります。The Illuminate\Mail\Message typically proxied missing methods to the underlying Swift_Message instance. However, missing methods are now proxied to an instance of Symfony\Component\Mime\Email instead. So, any code that was previously relying on missing methods to be proxied to SwiftMailer should be updated to their corresponding Symfony Mailer counterparts.

繰り返しますが、Laravelのドキュメントに記載されていないため、多くのアプリケーションはこれらのメソッドと関わっていないでしょう。Again, many applications may not be interacting with these methods, as they are not documented within the Laravel documentation:

// Laravel8.x
$message
    ->setFrom('taylor@laravel.com')
    ->setTo('example@example.org')
    ->setSubject('Order Shipped')
    ->setBody('<h1>HTML</h1>', 'text/html')
    ->addPart('Plain Text', 'text/plain');

// Laravel9.x
$message
    ->from('taylor@laravel.com')
    ->to('example@example.org')
    ->subject('Order Shipped')
    ->html('<h1>HTML</h1>')
    ->text('Plain Text');

生成するメッセージIDGenerated Messages IDs

SwiftMailerは、mime.idgenerator.idright設定オプションで、生成するメッセージIDに含めるカスタムドメインを定義することが可能でした。これはSymfony Mailerではサポートされていません。代わりに、Symfony Mailerは送信者に基づいてメッセージIDを自動的に生成します。SwiftMailer offered the ability to define a custom domain to include in generated Message IDs via the mime.idgenerator.idright configuration option. This is not supported by Symfony Mailer. Instead, Symfony Mailer will automatically generate a Message ID based on the sender.

MessageSentイベントの変更MessageSent Event Changes

Illuminate\Mail\Events\MessageSentイベントのmessageプロパティは、Swift_Messageインスタンスの代わりに、Symfony\Component\Mime\Emailインスタンスを含むようにしました。このメッセージは、送信前の電子メールを表します。The message property of the Illuminate\Mail\Events\MessageSent event now contains an instance of Symfony\Component\Mime\Email instead of an instance of Swift_Message. This message represents the email before it is sent.

さらに、MessageSentイベントへ、新しくsentプロパティを追加しました。このプロパティはIlluminate\Mail\SentMessageインスタンスを含み、メッセージIDなど送信したメールに関する情報を含んでいます。Additionally, a new sent property has been added to the MessageSent event. This property contains an instance of Illuminate\Mail\SentMessage and contains information about the sent email, such as the message ID.

再接続の強制Forced Reconnections

トランスポートの再接続を強制することはできなくなりました。(例:メーラーがデーモンプロセスで動作している場合)代わりに、Symfony Mailerは自動的にトランスポートへの再接続を試み、再接続が失敗した場合は例外を投げます。It is no longer possible to force a transport reconnection (for example when the mailer is running via a daemon process). Instead, Symfony Mailer will attempt to reconnect to the transport automatically and throw an exception if the reconnection fails.

SMTPストリームオプションSMTP Stream Options

SMTPトランスポートのストリームオプションの定義をサポートしなくなりました。代わりに、関連オプションがサポートされている場合、設定内で直接定義する必要があります。例として、TLSピア認証を無効にする場合をご覧ください。Defining stream options for the SMTP transport is no longer supported. Instead, you must define the relevant options directly within the configuration if they are supported. For example, to disable TLS peer verification:

'smtp' => [
    // Laravel8.x
    'stream' => [
        'ssl' => [
            'verify_peer' => false,
        ],
    ],

    // Laravel9.x
    'verify_peer' => false,
],

利用可能な設定オプションの詳細は、Symfony Mailer documentationを確認してください。To learn more about the available configuration options, please review the Symfony Mailer documentation[https://symfony.com/doc/6.0/mailer.html#transport-setup].

warning Warning! 上記に例として挙げましたが、SSL認証を無効にすることは、「中間者」攻撃の可能性をもたらすので、一般的にはおすすめできません。Warning
In spite of the example above, you are not generally advised to disable SSL verification since it introduces the possibility of "man-in-the-middle" attacks.

SMTP auth_modeSMTP auth_mode

SMTPのauth_modemail設定ファイルで定義する必要はなくなりました。認証モードは、Symfony MailerとSMTPサーバの間で自動的にネゴシエーションされます。Defining the SMTP auth_mode in the mail configuration file is no longer required. The authentication mode will be automatically negotiated between Symfony Mailer and the SMTP server.

Failed RecipientsFailed Recipients

メッセージ送信後に、失敗した受信者のリストを取得できなくなりました。代わりに、メッセージの送信に失敗すると、Symfony\Component\Mailer\Exception\TransportExceptionInterface例外が投げられるようになりました。メッセージ送信後に無効なメールアドレスの取得する代わりに、メッセージ送信前にメールアドレスの検証を行うことを推奨します。It is no longer possible to retrieve a list of failed recipients after sending a message. Instead, a Symfony\Component\Mailer\Exception\TransportExceptionInterface exception will be thrown if a message fails to send. Instead of relying on retrieving invalid email addresses after sending a message, we recommend that you validate email addresses before sending the message instead.

パッケージPackages

langディレクトリThe lang Directory

影響の可能性: 中程度Likelihood Of Impact: Medium

新しいLaravelアプリケーションでは、resources/langディレクトリがプロジェクトのルートディレクトリのlangへ配置しました。もし、あなたのパッケージがこのディレクトリへ直接言語ファイルをリソース公開していれば、パスをハードコードせずに、app()->langPath()へ確実にリソース公開してください。In new Laravel applications, the resources/lang directory is now located in the root project directory (lang). If your package is publishing language files to this directory, you should ensure that your package is publishing to app()->langPath() instead of a hard-coded path.

キューQueue

opis/closureライブラリThe opis/closure Library

影響の可能性: 低いLikelihood Of Impact: Low

Laravelの依存パッケージのopis/closurelaravel/serializable-closureへ置き換えました。opis/closureライブラリを直接操作していない限り、これによりアプリケーションへ互換性がない変更は起きません。付け加えて、以前、非推奨にしたIlluminate\Queue\SerializableClosureFactoryIlluminate\Queue\SerializableClosureクラスを削除しました。もし、opis/closureライブラリを直接操作したり、削除されたクラスを使用している場合は、代わりに Laravelシリアライズ可能クロージャ を使用してください。Laravel's dependency on opis/closure has been replaced by laravel/serializable-closure. This should not cause any breaking change in your application unless you are interacting with the opis/closure library directly. In addition, the previously deprecated Illuminate\Queue\SerializableClosureFactory and Illuminate\Queue\SerializableClosure classes have been removed. If you are interacting with opis/closure library directly or using any of the removed classes, you may use Laravel Serializable Closure[https://github.com/laravel/serializable-closure] instead.

失敗したジョブプロバイダのflushメソッドThe Failed Job Provider flush Method

影響の可能性: 低いLikelihood Of Impact: Low

Illuminate\Queue\Failed\FailedJobProviderInterfaceインターフェイスで定義したflushメソッドは、$hours引数を受けるようにしました。これは失敗したジョブをqueue:flushコマンドでフラッシュするまで何時間待つかを決定します。FailedJobProviderInterfaceを手作業で実装している場合、この新しい引数を反映するように実装を更新する必要があります。The flush method defined by the Illuminate\Queue\Failed\FailedJobProviderInterface interface now accepts an $hours argument which determines how old a failed job must be (in hours) before it is flushed by the queue:flush command. If you are manually implementing the FailedJobProviderInterface you should ensure that your implementation is updated to reflect this new argument:

public function flush($hours = null);

セッションSession

getSessionメソッドThe getSession Method

影響の可能性: 低いLikelihood Of Impact: Low

Laravel自身のIlluminate\Http\Requestクラスへ拡張されていたSymfony\Component\HttpFoundaton\Requestクラスは、現在のセッションストレージハンドラを取得するgetSessionメソッドを提供しています。ほとんどのLaravelアプリケーションは、Laravel自身のsessionメソッドを通してセッションと対話するので、Laravelはこのメソッドを文書化していません。The Symfony\Component\HttpFoundaton\Request class that is extended by Laravel's own Illuminate\Http\Request class offers a getSession method to get the current session storage handler. This method is not documented by Laravel as most Laravel applications interact with the session through Laravel's own session method.

以前のgetSessionメソッドは、Illuminate\Session\Storeインスタンスかnullを返していましたが、Symfony6.XはSymfony\Component\HttpFoundation\Session\SessionInterfaceタイプを返すように強制しています。そのため、getSessionは、SessionInterfaceの実装を返すか、セッションが存在しないときは\Symfony\Component\HttpFoundation\Exception\SessionNotFoundExceptionを投げるようになりました。The getSession method previously returned an instance of Illuminate\Session\Store or null; however, due to the Symfony 6.x release enforcing a return type of Symfony\Component\HttpFoundation\Session\SessionInterface, the getSession now correctly returns a SessionInterface implementation or throws an \Symfony\Component\HttpFoundation\Exception\SessionNotFoundException exception when no session is available.

テストTesting

assertDeletedメソッドThe assertDeleted Method

影響の可能性: 中程度Likelihood Of Impact: Medium

assertDeletedメソッドのすべての呼び出しをassertModelMissingへ更新してください。All calls to the assertDeleted method should be updated to assertModelMissing.

信用できるプロキシTrusted Proxies

影響の可能性: 低いLikelihood Of Impact: Low

Laravel8プロジェクトをLaravel9にアップグレードする際、既存のアプリケーションコードを全く新しいLaravel9アプリケーションスケルトンへインポートする場合、アプリケーションの「信用できるプロキシ」ミドルウェアを更新する必要がある場合があります。If you are upgrading your Laravel 8 project to Laravel 9 by importing your existing application code into a totally new Laravel 9 application skeleton, you may need to update your application's "trusted proxy" middleware.

app/Http/Middleware/TrustProxies.phpファイル中の、use Fideloper\Proxy\TrustProxies as Middlewareuse Illuminate\Http\Middleware\TrustProxies as Middlewareへ変更してください。Within your app/Http/Middleware/TrustProxies.php file, update use Fideloper\Proxy\TrustProxies as Middleware to use Illuminate\Http\Middleware\TrustProxies as Middleware.

次に、app/Http/Middleware/TrustProxies.php中の$headersプロパティ定義を更新します。Next, within app/Http/Middleware/TrustProxies.php, you should update the $headers property definition:

// 変更前
protected $headers = Request::HEADER_X_FORWARDED_ALL;

// 変更後
protected $headers =
    Request::HEADER_X_FORWARDED_FOR |
    Request::HEADER_X_FORWARDED_HOST |
    Request::HEADER_X_FORWARDED_PORT |
    Request::HEADER_X_FORWARDED_PROTO |
    Request::HEADER_X_FORWARDED_AWS_ELB;

最後に、アプリケーションからfideloper/proxyComposerの依存パッケージを削除します。Finally, you can remove the fideloper/proxy Composer dependency from your application:

composer remove fideloper/proxy

バリデーションValidation

フォームリクエストのvalidatedメソッドForm Request validated Method

影響の可能性: 低いLikelihood Of Impact: Low

フォームリクエストが提供しているvalidatedメソッドは、$key$default引数を取るようにしました。このメソッドの定義を独自に上書きしている場合は、これらの新しい引数を反映させるように更新してください。The validated method offered by form requests now accepts $key and $default arguments. If you are manually overwriting the definition of this method, you should update your method's signature to reflect these new arguments:

public function validated($key = null, $default = null)

passwordルールThe password Rule

影響の可能性: 中程度Likelihood Of Impact: Medium

与えられた入力値が認証済みユーザーの現在のパスワードと一致するかをバリデートするpasswordルールの名前をcurrent_passwordへ変更しました。The password rule, which validates that the given input value matches the authenticated user's current password, has been renamed to current_password.

Unvalidated Array KeysUnvalidated Array Keys

影響の可能性: 中程度Likelihood Of Impact: Medium

Laravelの以前のリリースでは、Laravelのバリデータが返す「バリデーション済み」データから、バリデーションしていない配列キーを除外するには、手作業で指示する必要がありました。特に、許容するキーのリストを指定しないarrayルールと組み合わせた場合です。In previous releases of Laravel, you were required to manually instruct Laravel's validator to exclude unvalidated array keys from the "validated" data it returns, especially in combination with an array rule that does not specify a list of allowed keys.

しかし、Laravel9.xでは、arrayルールで許可するキーを指定していない場合でも、バリデーションしていない配列キーは常に「バリデーション済み」データから除外されます。通常、この動作は最も期待されている動作であり、以前のexcludeUnvalidatedArrayKeysメソッドは、Laravel8.xで下位互換性を保つための一時的な措置として追加したものでした。However, in Laravel 9.x, unvalidated array keys are always excluded from the "validated" data even when no allowed keys have been specified via the array rule. Typically, this behavior is the most expected behavior and the previous excludeUnvalidatedArrayKeys method was only added to Laravel 8.x as a temporary measure in order to preserve backwards compatibility.

推奨はしませんが、アプリケーションのサービスプロバイダのbootメソッド内で、新しいincludeUnvalidatedArrayKeysメソッドを呼び出し、以前のLaravel8.x の動作を選択することもできます。Although it is not recommended, you may opt-in to the previous Laravel 8.x behavior by invoking a new includeUnvalidatedArrayKeys method within the boot method of one of your application's service providers:

use Illuminate\Support\Facades\Validator;

/**
 * アプリケーションの全サービスの登録
 *
 * @return void
 */
public function boot()
{
    Validator::includeUnvalidatedArrayKeys();
}

その他Miscellaneous

また、laravel/laravel GitHubリポジトリで、変更点を確認することをおすすめします。これらの変更の多くは必須ではありませんが、これらのファイルをあなたのアプリケーションへ同期させておくとよいでしょう。こうした変更の一部は、このアップグレードガイドでカバーしますが、設定ファイルやコメントの変更のような他のものは、カバーしません。GitHub比較ツールで簡単に変更点を確認し、どの更新が皆さんにとって重要か選択できます。We also encourage you to view the changes in the laravel/laravel GitHub repository[https://github.com/laravel/laravel]. While many of these changes are not required, you may wish to keep these files in sync with your application. Some of these changes will be covered in this upgrade guide, but others, such as changes to configuration files or comments, will not be. You can easily view the changes with the GitHub comparison tool[https://github.com/laravel/laravel/compare/8.x...9.x] and choose which updates are important to you.

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作