5.3から5.4.0へのアップグレード
アップグレード見積もり時間 1〜2時間
Note: 私達は互換性を失う可能性がある変更を全部ドキュメントにしようとしています。しかし、変更点のいくつかはフレームワークの明確ではない部分で行われているため、一部の変更が実際にアプリケーションに影響を与えてしまう可能性があります。
依存パッケージのアップデート
composer.json
ファイル中の、laravel/framework
依存パッケージ指定のバージョンを5.4.*
へ更新してください。さらに、依存パッケージのphpunit/phpunit
を~5.7
へ更新してください。
コンパイル済みサービスファイルの削除
存在している場合は、bootstrap/cache/compiled.php
ファイルを削除してください。フレームワークで使用しなくなりました。
キャッシュのクリア
全パッケージを更新したら、Illuminate\View\Factory::getFirstLoop()
の削除に関連するBladeのエラーを防ぐために、php artisan view:clear
を実行してください。さらに、ルートキャッシュをクリアするために、php artisan route:clear
も行う必要があります。
Laravel Cashier
Laravel CashierはLaravel5.4へ既に対応しています。
Laravel Passport
Laravel Passport 2.0.0
は既にLaravel5.4とAxios
JavaScriptライブラリへ対応しています。Laravel5.3で既に構築済みのPassprt
Vueコンポーネントを使用中の場合は、Axiosライブラリをaxios
としてアプリケーション全体で、確実に使用できるようにしてください。
Laravel Scout
Laravel Scout
3.0.0
はLaravel5.4へすでに対応済みです。
Laravel Socialite
Laravel Socialite
3.0.0
はLaravel5.4へすでに対応済みです。
Laravel Tinker
tinker
Artisanコマンドを続けて使用する場合は、laravel/tinker
パッケージもインストールする必要があります。
composer require laravel/tinker
パッケージをインストールしたら、config/app.php
設定ファイルのproviders
配列へ、Laravel\Tinker\TinkerServiceProvider::class
を追加してください。
Guzzle
Laravel5.4では、Guzzleのバージョン6.0以上が必要です。
認証
getPolicyFor
メソッド
以前のバージョンで、Gate::getPolicyFor($class)
メソッドはポリシーが見つからない場合に例外を投げていました。現在、このメソッドは指定クラスのポリシーが見つからない場合、null
を返します。このメソッドを直接呼び出している場合、null
を判定するようにコードをリファクタリングしてください。
$policy = Gate::getPolicyFor($class);
if ($policy) {
// 以前のtryブロックの中のコード
} else {
// 以前のcatchブロックの中のコード
}
Blade
@section
エスケープ
セクションに渡されるインラインコンテンツをLaravel5.4は自動的にエスケープします。
@section('title', $content)
セクション中のコンテンツをエスケープしないでレンダしたいときは、もとの「長い記法」を使用してください。
@section('title')
{!! $content !!}
@stop
Bootstrappers
HTTPとConsoleカーネルの$bootstrappers
配列をオーバーライドしている場合は、DetectEnvironment
エントリをLoadEnvironmentVariables
へリネームし、ConfigureLogging
を削除してください。
ブロードキャスト
チャンネルモデル結合
Laravel5.3でチャンネル名のプレースフォルダを定義する場合、*
文字を使用しました。Laravel5.4では、ルートと同様に{foo}
スタイルのプレースホルダを使用し定義してください。
Broadcast::channel('App.User.{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
コレクション
every
メソッド
every
メソッドの振る舞いは、Lodashにより定義されたメソッド名と一致するように、nth
メソッドへ移動しました。
random
メソッド
$collection->random(1)
の呼び出しは、アイテムを一つ持った新しいコレクションを返すようになりました。以前のこのメソッドは、1オブジェクトを返していました。現在、引数を指定しない場合に1オブジェクトを返します。
コンテナ
bind
とinstance
によるエイリアス
以前のバージョンのLaravelでは、bind
やinstance
メソッドの第1引数に、登録するエイリアスを配列で渡しました。
$container->bind(['foo' => FooContract::class], function () {
return 'foo';
});
Laravel5.4では、この振る舞いは削除されました。エイリアスを登録するには、alias
メソッドを使用してください。
$container->alias(FooContract::class, 'foo');
スラッシュが先頭につく結合クラス
スラッシュが先頭に付く結合クラスのコンテナへの登録は、サポートされなくなりました。この機能を実現するために、コンテナ内で数多くの文字列整形を呼び出す必要がありました。シンプルにスラッシュで始まらない結合を登録してください。
$container->bind('Class\Name', function () {
//
});
$container->bind(ClassName::class, function () {
//
});
make
メソッド引数
make
メソッドは第2引数に引数の配列を受け取らなくなりました。この機能の使用は、通常悪いコードの印です。通常、より直感的な他の方法でオブジェクトを構築できます。
Resolvingコールバック
コンテナのresolving
とafterResolving
メソッドは、最初の引数としてクラス名か結合キーを指定する必要があります。
$container->resolving('Class\Name', function ($instance) {
//
});
$container->afterResolving('Class\Name', function ($instance) {
//
});
share
メソッドの削除
share
メソッドはコンテナから削除されました。これは古いメソッドで、数年間ドキュメントに記載されていません。このメソッドを使用しているのであれば、代わりにsingleton
メソッドを使ってください。
$container->singleton('foo', function () {
return 'foo';
});
コンソール
Illuminate\Console\AppNamespaceDetectorTrait
トレイト
直接Illuminate\Console\AppNamespaceDetectorTrait
を使用しているのであれば、代わりにIlluminate\Console\AppNamespaceDetectorTrait
を使用するようにコードを更新してください。
データベース
カスタム接続
以前のバージョンで、カスタムデータベース接続インスタンスを依存解決するために、サービスコンテナへdb.connection.{ドライバ名}
キーを結合していたのであれば、AppServiceProvider
のregister
メソッドの中で、Illuminate\Database\Connection::resolverFor
メソッドを呼び出してください。
use Illuminate\Database\Connection;
Connection::resolverFor('ドライバ名', function ($connection, $database, $prefix, $config) {
//
});
フェッチモード
Laravelは設定ファイルからのPDO「フェッチモード」のカスタマイズ機能を提供しなくなりました。代わりに、PDO::FETCH_OBJ
がいつでも利用できます。アプリケーションのためにフェッチモードを依然カスタマイズするのであれば、新しいIlluminate\Database\Events\StatementPrepared
イベントをリッスンしてください。
Event::listen(StatementPrepared::class, function ($event) {
$event->statement->setFetchMode(...);
});
Eloquent
日付キャスト
date
キャストはカラムをCarbon
オブジェクトに変換するようになり、このオブジェクトのstartOfDay
メソッドを呼び出します。日付の時間部分を残したい場合は、datetime
キャストを使用してください。
外部キー命名規則
リレーションの定義時に、外部キーを明確に指定しない場合、Eloquentは関連モデルのテーブル名と主キー名を外部キーの構築に使用するようになりました。ほとんどのアプリケーションでは、これによる振る舞いの変更はありません。例をご覧ください。
public function user()
{
return $this->belongsTo(User::class);
}
以前のバージョンのLaravelと同様に、このリレーションは通常外部キーとしてuser_id
を使用します。しかし、User
モデルのgetKeyName
メソッドをオーバーライドしている場合は、振る舞いが異なります。例を見てください。
public function getKeyName()
{
return 'key';
}
このケースの場合、Laravelはカスタマイズを尊重するようになり、user_id
の代わりにuser_key
外部キーカラム名として利用します。
BelongsToManyのsetJoin
setJoin
メソッドは、performJoin
へリネームされました。
hasOne
とhasMany
のcreateMany
hasOne
とhasMany
リレーションのcreateMany
メソッドは、配列の代わりにコレクションオブジェクトを返すようになりました。
関連モデルの接続
親のモデルと同じ接続を関連するモデルでも使用するようになりました。次のようにクエリを実行できます。
User::on('example')->with('posts');
Eloquentはデフォルトデータベース接続の代わりに、example
接続のpostsテーブルをクエリします。デフォルト接続のposts
リレーションを読み込みたい場合は、明確にモデルの接続をアプリケーションのデフォルトへ設定してください。
chunk
メソッド
クエリービルダーのchunk
メソッドは、each
メソッドとの一貫性を保つため、orderBy
節が必要になりました。orderBy
節が指定されていない場合、例外が投げられます。例をご覧ください。
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
foreach ($users as $user) {
//
}
});
Eloquentクエリービルダーのchunk
メソッドでは指定されていない場合、orderBy
節にモデルの主キーを自動的に適用します。
create
とforceCreate
メソッド
複数接続によるモデル生成をより良くサポートするため、Model::create
とModel::forceCreate
はIlluminate\Database\Eloquent\Builder
へ移動しました。しかし、皆さん自身のモデルの中で、これらのメソッドを拡張している場合は、ビルダーに対しcreate
メソッドを呼び出すように、実装を変更する必要があります。
public static function create(array $attributes = [])
{
$model = static::query()->create($attributes);
// ...
return $model;
}
hydrate
メソッド
今までこのメソッドにはカスタム接続名を渡していましたが、on
メソッドを使うようになりました。
User::on('connection')->hydrate($records);
hydrateRaw
メソッド
Model::hydrateRaw
メソッドはfromQuery
へリネームされました。このメソッドへカスタム接続名を渡す場合は、on
メソッドを使用してください。
User::on('connection')->fromQuery('...');
whereKey
メソッド
whereKey($id)
メソッドは主キーの値を指定するために"where"節を追加するようになりました。以前のこのメソッドは、動的"where"節ビルダで処理され、"key"カラムへの"where"を追加していました。whereKey
メソッドでkey
カラムへの条件を動的に使っていた場合は、where('key', ...)
を変わりに使用してください。
factory
ヘルパ
factory(User::class, 1)->make()
やfactory(User::class, 1)->create()
の呼び出しは、アイテム一つのコレクションを返すようになりました。以前のバージョンでは、モデルを1つ返していました。このメソッドは数を指定しない場合に、モデルを1つ返します。
イベント
Contract Changes
アプリケーションやパッケージで、Illuminate\Contracts\Events\Dispatcher
インターフェイスを直接実装している場合は、fire
メソッドをdispatch
へリネームしてください。
イベントプライオリティ
イベントハンドラの「プライオリティ」サポートは削除されました。このドキュメントに記載されていない機能は、通常イベント機能を間違って使用していることを示します。代わりに、同期的にメソッドを順番に呼び出してください。もしくは、イベントハンドラの中から別の新しいイベントをディスパッチしすることで、ハンドラ処理の順番をコントロールしてください。
ワイルドカードイベントハンドラ使用法
ワイルドカードイベントハンドラは、イベント名を最初の引数に、イベントデータを2つ目の引数に受け取るようになりました。Event::firing
メソッドは削除されました。
Event::listen('*', function ($eventName, array $data) {
//
});
kernel.handled
イベント
kernel.handled
イベントは、オブジェクトベースイベントのIlluminate\Foundation\Http\Events\RequestHandled
クラスを使用するようになりました。
locale.changed
イベント
locale.changed
イベントは、オブジェクトベースイベントのIlluminate\Foundation\Events\LocaleUpdated
クラスを使用するようになりました。
illuminate.log
イベント
illuminate.log
イベントは、オブジェクトベースイベントのIlluminate\Log\Events\MessageLogged
クラスを使用するようになりました。
例外
Illuminate\Http\Exception\HttpResponseException
はIlluminate\Http\Exceptions\HttpResponseException
へリネームされました。Exceptions
と複数形になっていることに注意してください。同様に、Illuminate\Http\Exception\PostTooLargeException
はIlluminate\Http\Exceptions\PostTooLargeException
へリネームされました。
メール
クラス@メソッド
記法
メール送信のクラス@メソッド
記法はサポートされなくなりました。
Mail::send('view.name', $data, 'クラス@メソッド');
上記のようにメールを送信しているのであれば、Mailableを呼び出すように変更してください。
新しい設定オプション
Laravel5.4では新しくMarkdownメールコンポーネントをサポートするようになったため、mail
設定ファイルの最後に、以下の設定ブロックを追加してください。
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
クロージャーを使用したメールのキュー投入
メールをキューに投入するため、Mailableを使用する必要があります。Mail::queue
とMail::later
を使用するメールのキューイングには、メールメッセージを設定するためのクロージャは、サポートされなくなりました。PHPはネイティブにクロージャのシリアライズをサポートしていないため、この機能を実現するために特別なライブラリを必要としていました。
キュー
失敗したジョブのテーブル
アプリケーションが、failed_jobs
テーブルを含んでいる場合は、exception
カラムをそのテーブルへ追加してください。
$table->longText('exception')->after('payload');
Redis
クラスタサポートの向上
Laravel5.4では、Redisクラスタのサポートが向上しました。Redisクラスタを使用する場合、config/database.php
設定ファイルのRedis設定のclusters
オプションの中で、クラスタ接続を指定する必要があります。
'redis' => [
'client' => 'predis',
'options' => [
'cluster' => 'redis',
],
'clusters' => [
'default' => [
[
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
],
],
ルーティング
Postサイズミドルウェア
Illuminate\Foundation\Http\Middleware\VerifyPostSize
クラスは、Illuminate\Foundation\Http\Middleware\ValidatePostSize
へリネームされました。
middleware
メソッド
Illuminate\Routing\Router
クラスのmiddleware
メソッドは、aliasMiddleware()
へリネームされました。HTTPカーネルが$routeMiddleware
配列中で定義されている、ルートレベルのミドルウェアを登録するために呼び出しているだけですので、ほとんどのアプリケーションではこのメソッドを直接呼び出すことはないでしょう。
Route
メソッド
Illuminate\Routing\Route
クラスのgetUri
メソッドは削除されました。uri
メソッドを代わりに使用してください。
Illuminate\Routing\Route
クラスのgetMethods
メソッドは削除されました。methods
メソッドを代わりに使用してください。
Illuminate\Routing\Route
クラスのgetParameter
メソッドは削除されました。parameter
メソッドを変わりに使用してください。
Illuminate\Routing\Route
クラスのgetPath
メソッドは削除されました。uri
メソッドを代わりに使ってください。
セッション
Symfonyコンパチビリティ
Laravelのセッションハンドラは、SymfonynのSessionInterface
を実装しなくなりました。これを実装するとフレームワークで使用しない無関係な機能を実装する必要があるためです。代わりに新しいIlluminate\Contracts\Session\Session
インターフェイスが定義され、代わりに使用されした。以下の変更も行われました。
->set()
メソッドの呼び出しは、全て->put()
へ変更してください。ドキュメントに含めていないため、Laravelアプリケーションではset
メソッドを通常呼び出していないでしょう。しかし、注意してください。
->getToken()
メソッドの呼び出しは、全て->token()
へ変更してください。
$request->setSession()
メソッドの呼び出しは、全てsetLaravelSession()
へ変更してください。
テスト
Laravel5.4のテストレイヤは、より簡単で、より軽くなるように書き直されました。Laravel5.3のテストレイヤを続けて使用したい場合は、アプリケーションにlaravel/browser-kit-testing
パッケージをインストールしてください。このパッケージは、Laravel5.3のテストレイヤと完全な互換性があります。実のところ、Laravel5.4のテストレイヤを実行しながら、Laravel5.3テストレイヤも使用できます。
Laravel5.4のテストジェネレータを使用し生成した新しいテストを利用するため、Laravelがオートロード可能なように、composer.json
ファイルのautoload-dev
ブロックに、Tests
名前空間を追加してください。
"psr-4": {
"Tests\": "tests/"
}
同じアプリケーションでLaravel5.3と5.4のテストを実行する
まず、laravel/browser-kit-testing
パッケージをインストールします。
composer require laravel/browser-kit-testing="1.*" --dev
インストールしたら、tests/TestCase.php
ファイルをtests
ディレクトリへBrowserKitTestCase.php
として保存します。それから、Laravel\BrowserKitTesting\TestCase
クラスを拡張するように、このファイルを変更してください。これが終わると、tests
ディレクトリ下にTestCase.php
とBrowserKitTestCase.php
、2つのベーステストクラスが用意されます。BrowserKitTestCase
クラスを確実にロードするために、composer.json
ファイルへ追加する必要があります。
"autoload-dev": {
"classmap": [
"tests/TestCase.php",
"tests/BrowserKitTestCase.php"
]
},
Laravel5.3上で書かれたテストは、BrowserKitTestCase
クラスを拡張し、Laravel5.4テストレイヤを使用して書かれた新しいテストは、TestCase
クラスを拡張します。BrowserKitTestCase
クラスは以下のようになります。
<?php
use Illuminate\Contracts\Console\Kernel;
use Laravel\BrowserKitTesting\TestCase as BaseTestCase;
abstract class BrowserKitTestCase extends BaseTestCase
{
/**
* アプリケーションのベースURL
*
* @var string
*/
public $baseUrl = 'http://localhost';
/**
* アプリケーションの作成
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
}
このクラスを作成したら、全テストで新しいBrowserKitTestCase
クラスを拡張するように更新してください。これにより、Laravel5.3上で書かれたテストは、続けてLaravel5.4でも実行できるようになります。お望みであれば、少しずつそれらのテストをLaravel5.4記法やLaravel Duskへ移行してください。
Note: 新しいテストを書き、Laravel5.4テストレイヤで使用する場合は、確実に
TestCase
クラスを拡張してください。
アップデート済みアプリケーションへのDuskインストール
Laravel5.3からアップグレードしたアプリケーションに、Laravel Duskをインストールしたい場合は、最初にComposerを使用し、インストールします。
composer require laravel/dusk
次に、tests
ディレクトリ下にCreatesApplication
トレイトを作成する必要があります。このトレイトはテストケースに対して、真新しいアプリケーションインスタンスを生成することに責任を負います。このトレイトは次のような内容です。
<?php
use Illuminate\Contracts\Console\Kernel;
trait CreatesApplication
{
/**
* アプリケーションの作成
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
}
Note: テストに名前空間を付けており、
tests
ディレクトリのロードにPSR-4オートロード規約を使用してい場合は、適切な名前空間下にCreatesApplication
トレイトを設置してください。
これらの手順をやり終えたら、通常通りのDuskインストール手順に従ってください。
環境
Laravel5.4テストクラスは、各テストごとにputenv('APP_ENV=testing')
を共用しなくなりました。代わりにフレームワークは、読み込んだ.env
ファイルのAPP_ENV
変数を使用します。
Event Fake
Event
FakeのassertFired
メソッドはassertDispatched
へ、assertNotFired
メソッドはassertNotDispatched
へ変更してください。メソッドの使い方に変更はありません。
Mail Fake
Laravel5.4で、Mail
Fakeはとても簡略化されました。assertSentTo
メソッドを使用する代わりに、assertSent
メソッドを使用し、hasTo
、hasCc
などのヘルパメソッドをコールバック内で使用してください。
Mail::assertSent(MailableName::class, function ($mailable) {
return $mailable->hasTo('email@example.com');
});
翻訳
{Inf}
プレースホルダ
{Inf}
を翻訳文字列の複数形に対するプレースホルダとして使用している場合は、代わりに*
文字を使用するように翻訳文字列を変更してください。
{0} First Message|{1,*} Second Message
trans
ヘルパ
trans
ヘルパの使用法は、不必要な$domain
引数を削除するように変更されました。新しい引数は以下のとおりです。
/**
* 指定メッセージの翻訳
*
* @param string $id
* @param array $replace
* @param string $locale
* @return \Illuminate\Contracts\Translation\Translator|string|array|null
*/
function trans($id = null, $replace = [], $locale = null);
また、trans_choice
ヘルパも変更されました。
/**
* Translates the given message based on a count.
*
* @param string $id
* @param int|array|\Countable $number
* @param array $replace
* @param string $locale
* @return string
*/
function trans_choice($id, $number, array $replace = [], $locale = null);
URL生成
forceSchema
メソッド
Illuminate\Routing\UrlGenerator
クラスのforceSchema
メソッドは、forceScheme
へリネームされました。
バリデーション
日付フォーマットのバリデーション
日付フォーマットのバリデーションはより厳格になり、PHPの日付関数のドキュメント内に記載のあるプレースホルダをサポートしました。以前のバージョンのLaravelでは、タイムゾーンのプレースホルダであるP
は全タイムゾーンフォーマットを受け付けていました。しかし、Laravel5.4ではPHPドキュメントに従い、それぞれのタイムゾーンフォーマットごとに独自のプレースホルダを指定してください。
メソッド名
addError
メソッドはaddFailure
へリネームされました。更に、doReplacements
メソッドもmakeReplacements
へリネームされました。通常、これらの変更はValidator
クラスを拡張している場合に影響します。
その他
laravel/laravel
GitHubリポジトリで、変更を確認することもおすすめします。それらの多くの変更は必要ないでしょうが、皆さんのアプリケーションで同期を保ちたいでしょう。変更の一部はこのアップグレードガイドに記載されていますが、設定ファイルやコメントなどの変更は乗っていません。GitHubの比較ツールで変更を簡単に確認できますし、皆さんにとって重要な変更を選び出すこともできます。