Laravel 5.5を使用するにはPHP 7.0以上が必要です。PHPの新機能は、Learn PHP 7, Find out What’s New, and Moreにまとめています。
Laravel 5.5は次期LTS(Long Term Support)リリースに該当し、2年間のバグ修正と3年間のセキュリティ更新が保証されています。Laravel 5.1もLTSでしたが、2年のバグ修正期間が今年で終了します。
Laravel 5.5の機能を紹介します。
Laravel 5.5で新しいプロジェクトを作成
本記事執筆時点では正式版はリリースされていないため、開発者バージョンを次のコマンドでインストールします(日本版編注:8月30日にリリースされた)。
laravel new laravel55 --dev
cd laravel55
php artisan key:generate
Laravelインストーラーの代わりにComposerも可能です。
composer create-project --prefer-dist --stability=dev laravel/laravel:dev-master
cd laravel
php artisan key:generate
新しく作成したアプリのホームページに移動すると、既存のLaravelに類似したWelcomeページが表示されます。
Mailableをブラウザーにレンダリングする
LaravelでEmailテンプレートをテストするには、実際にメールを送信するかMailtrapをはじめEmailクライアントが必要でした。しかしLavel5.5では、Emailのレイアウトをブラウザーに直接レンダリングできます。
この機能を試すために、現在のプロジェクトにMailableとEmailテンプレートを作成します。
php artisan make:mail Welcome --markdown=emails.welcome
コンテンツが用意されているテンプレートからMarkdownを使います。web.phpを開いてRouteを作成し、Emailのレイアウトを表示します。
Route/emailに移動すると、Emailテンプレートのプレビューが表示されます。
Laravel 5.5のMailableクラスは、render()メソッドを持つRenderableコントラクトを継承しています。lluminate/Mail/Mailable.phpのrender()メソッドは次の通りです。
このメソッドを使ってプレビューを表示します。もしRenderableコントラクトを継承しないクラスのインスタンスを先ほどのRouteで返すと、UnexpectedValueExceptionが発生します。
Emailテーマのカスタマイズ
LaravelでEmailにMarkdownを使うとデフォルトのテーマが使用されますが、自社のブランドイメージに合ったEmailテンプレートも作成できます。
特定のMailableテーマをカスタマイズするは、スタイルを.cssファイルに記述します。
touch resources/views/vendor/mail/html/themes/custom.css
ファイル名をMailableクラスのプロパティに指定します。
custom.cssに記述したスタイルのEmailをレイアウトします。この手法は、Mailableごとテーマを変えられるメリットがあります。
例外のヘルパー関数
Laravel 5.5には例外のヘルパー関数throw_ifとthrow_unlessメソッドがあり、簡潔にコードを記述できます。どちらも引数は3つで、最後の引数は省略可能です。
実際の使用例を紹介します。
$number = 2;
throw_if($number !== 3, new NotThreeException('Number is not three'));
// or
throw_if($number !== 3, NotThreeException::class, 'Number is not three');
throw_ifを使うと、最初の引数がTrueのときに例外が発生します。
throw_unlessも同様に使えますが、throw_ifとは異なり、最初の引数がFalseのときに例外が発生します。
$number = 2;
throw_unless($number === 3, new NotThreeException('Number is not three'));
// or
throw_unless($number === 3, NotThreeException::class, 'Number is not three');
あまり良い例ではありませんが、使い方が分かると思います。
migrate:freshコマンドを使う
データベースの再構築は、前バージョンでは、php artisan migrate:refreshコマンドを使いました。migrate:refreshコマンドは、migrationファイルごとdownメソッドに指定した内容に基づき、すべてのmigrationをロールバックして、再度migrationを実行します。
しかし外部キー制約があったりdown()メソッドに不備があったりすると、問題が発生し、手作業でテーブルを削除します(CLIか適当なGUIを使って)。新しいmigrate:freshコマンドなら、すべてのテーブルを削除して既存のmigrationをすべて再実行します。
JSONエラーのスタックトレース
前バージョンではAPI構築中にエラーが発生するたび、PostmanをはじめAPIクライアントからHTML形式でエラーが表示されました。Laravel 5.5ではHTMLではなくJSONスタックトレースで表示されるので、読みやすくなりました。
パッケージディスカバリーの自動化
Laravelプロジェクトでサードパーティのパッケージを使用する手順です。
- パッケージをインストール
- パッケージのサービスプロバイダーを登録
- Facadeを登録(該当すれば)
Laravel 5.5では、パッケージディスカバリーの自動化を使い、パッケージをrequireするだけで使用できます。ただしパッケージのプロバイダーが自動化に対応している必要があります。
自動化に対応済みのDebugbarパッケージは、composer.jsonにextraセクションが追加されています。
"extra": {
"laravel": {
"providers": [
"Foo\\Bar\\ServiceProvider"
],
"aliases": {
"Bar": "Foo\\Bar\\Facade"
}
}
}
パッケージのプロバイダーは、composer.jsonにextraセクションを追加して、providersとaliasesを指定します。
パッケージディスカバリーの自動化には、依存オブジェクトを削除しても壊れないメリットもあります。通常はパッケージをアンインストールしてもパッケージのサービスプロバイダーとFacadeはconfig/app.phpに残り、問題を引き起こすことがあります。
自動化なら、パッケージをComposerで削除したときに、パッケージに関連するすべてを削除します。
vendor:publishコマンドの変更点
前バージョンでvendor:publishコマンドを実行すると、MigrationやView、Configを含むパッケージのリソースすべてとフレームワークの一部のリソースが公開されました。
Laravel 5.5では、公開対象を指定してこのコマンドを実行します。フラグを渡さずにphp artisan vendor:publishを実行すると、プロバイダーかタグの選択を求められるので、公開する対象を指定します。詳しくは次のスクリーンショットを見てください。
publishコマンドに-allか--providerフラグを付けて実行すると、先ほどのプロンプトは表示されません。
php artisan vendor:publish --all
フロントエンドプリセットの品ぞろえ
Laravel 5.3と5.4では、フロントエンド向けにデフォルトでVueとBootstrapのスキャフォールドがありました。5.5ではデフォルトではありませんが、Reactが加わりました。
フロントエンドのプリセットを管理するartisanコマンドも追加され、使いたいスキャフォールドだけプリセットできます。Vue、Bootstrap、Reactなどのデフォルトのプリセットではなく、ほかのフロントエンドフレームワークを使いたい場合は、次のコマンドを使用します。
php artisan preset none
このコマンドを実行すると、既存のフロントエンドスキャッフォールドがすべて削除されます。たとえばReactでフロントエンドを開発したければ、次のコマンドでReactのスキャッフォールドを入手します。
php artisan preset react
このコマンドを実行したときのスクリーンショットです。
Whoopsが戻ってきた!
Laravel 5.5になってWhoops!が戻ってきて、エラー表示の方法が変わりました。Whoops!は開発途中でエラーが起こると、エラーになったコードの行をスクリーンショットとエラーメッセージで表示します。
新しいハンドラ―が追加されて、読みやすいエラーメッセージになりました。エラーになったコードの行をスクリーンショットで確認できるので、デバッグしやすくなりました。
Whoopsには、関連するファイルをIDEかエディターで直接開く機能があります。エディターがインストールされているマシンからPHPのソースファイルに直接アクセスできる必要があります。app/Exceptions/Handler.phpを開いて、次のコードを追加します。
$handler->setEditor('sublime')の行は、ベースクラスのwhoopsHandler()メソッドをオーバーライドして、リンクをSublime Textで開きます。ほかのエディターを使っているなら、ここでサポートされているエディターの一覧と追加方法を確認できます。また、iOSで使うにはSublime URLプロトコルのダウンロードが必要です。
例外レポートメソッドのカスタマイズ
以前のバージョンでは、特定の方法で発生させたLaravelのカスタムな例外を処理するには、ロジックをHandler.phpのreportメソッドに記述しました。下記は一例です。
仮にカスタム例外が50なら、乱雑なコードになるでしょう。
Laravel 5.5は、カスタム例外を処理するreport()メソッドを例外の中に記述できます。
ファクトリージェネレーターのモデル
Laravel 5.5で、モデルファクトリーを作成するコマンドが追加されました。モデルファクトリーは、テストにおけるフェイクデータの生成や、あるオブジェクトのインスタンス作成に便利です。
特定のクラスのファクトリーを作成するには、次のコマンドを実行します。
php artisan make:factory Post
database/factoriesに移動すると、PostFactoryクラスが表示されます。
関心の分離に従ったこのアプローチは、旧来より優れています。前バージョンでは、ファクトリーはすべてapp/factories/ModelFactory.phpに記述していました。
バリデートデータを返す
Laravel 5.5は、バリデートメソッドから受け取ったデータを、createメソッドに渡せます。これまでのLaravelでは、新しいオブジェクトを作成していました。
public function store()
{
$this->validate(request(), [
'title' => 'required',
'body' => 'required'
]);
// return Post::create(request()->only(['title', 'body'])); or
return Post::create(request()->all());
}
Laravel 5.5では、バリデートされたデータから直接オブジェクトを作成できます。
public function store()
{
$post = $this->validate(request(), [
'title' => 'required',
'body' => 'required'
]);
return Post::create($post);
}
Laravel 5.5では、requestインスタンスからvalidateメソッドを直接実行できます。
public function store()
{
$post = request()->validate([
'title' => 'required',
'body' => 'required'
]);
return Post::create($post);
}
この方法でオブジェクトを生成すると、バリデートメソッドで初期化していない属性は値を持ちません。作成するオブジェクトのすべての属性を初期化するために、バリデートが不要でも、バリデートメソッドにすべての属性に対する値を渡します。
$post = request()->validate([
'title' => 'required',
'body' => 'required',
'notRequiredField' => '',
]);
return Post::create($post);
バリデーションルールに縛られることなく、許可されたrequestデータにフィールドを自動で追加します。
バリデーションルールのカスタマイズ
ルールとメッセージをAppServiceProviderファイルとresources/lang/en/validation.phpファイルに分けて記述して、Validator::extendメソッドを使えば、前バージョンでも可能でした。LaravelドキュメントにLaravel 5.4で実装する方法が記載されています。
Laravel 5.5では、カスタムバリデーションを定義するartisanコマンドが追加されました。Ruleコントラクトを実装する新しいクラスを作成します。新しいルールを追加して、作成されるファイルの中身を確認します。
php artisan make:rule CustomRule
app/Rules/CustomRule.phpには、passesメソッドとmessageメソッドがあります。passesメソッドの引数はattributeとvalueで、booleanを返します。$attributeはバリデートするフィールドで、$valueはその属性に渡す実際の値です。
例として、アプリが特定の名前を受け付けないようにします。Ruleは以下の通りです。
新しいRuleでusername属性をバリデートします。
Taylor Otwellの記事で、Laravel 5.5でカスタムバリデーションを定義する方法が詳しく紹介されています。
Collectionに追加されたDDとDump
Collectionにdump()メソッドとdd()メソッドが追加されました。これまでのLaravelはCollectionのデバッグで、変数を格納したCollectionが変更されるたびに、変数をダンプしました。Laravel 5.5では、直接dd()かdump()をCollectionから呼び出せるので、デバッグしやすくなりました。
PostのCollectionが変更されるたびに中身を確認する方法は以下の通りです。
$posts = Post::all();
$posts
->dump()
->sorBy('title')
->dump()
->pluck('title')
->dump();
以下のように出力されます。
Collection {#284 ▼
#items: array:3 [▼
0 => Post {#285 }
1 => Post {#286 }
2 => Post {#287 }
]
}
Collection {#272 ▼
#items: array:3 [▼
0 => Post {#285 }
2 => Post {#287 }
1 => Post {#286 }
]
}
Collection {#268 ▼
#items: array:3 [▼
0 => "Aida Bosco"
1 => "Madge Leuschke"
2 => "Miss Bulah Armstrong Jr."
]
}
Collectionの中身を簡単に確認できます。ただし、dump()とdd()の違いは、dump()は最新の結果を出力して処理を継続しますが、dd()は処理を停止して結果をダンプします(ddはdump and dieの略です)。Collectionからdd()を繰り返し呼び出しても、1回目のdd()だけが結果を出力します。次のコードを見てください。
$posts = Post::all();
$posts
->dump()
->sorBy('title')
->dd()
->pluck('title')
->dump();
以下のように出力されます。
Collection {#284 ▼
#items: array:3 [▼
0 => Post {#285 }
1 => Post {#286 }
2 => Post {#287 }
]
}
array:3 [▼
0 => Post {#285 }
2 => Post {#287 }
1 => Post {#286 }
]
多対多をキャストするPivotテーブル
通常は属性の保存と読み込み方法を定義するModelにcastsプロパティを宣言します。PostModelと数個のフィールドを考えます。フィールドの1つは読み込みと書き込み時にJSONをシリアライズします。以下のコードで実装します。
class Post extends Model
{
[...]
protected $casts = [
'somefield' => 'array',
];
[...]
}
Laravel 5.4から読み込みの場合のみ多対多の関係にあるカスタムPivotのキャストも可能です。書き込みは、属性の値を手動でキャストしてから保存します。Laravel 5.5では、Eloquent\Relations\Pivotクラスの$castsプロパティにEloquent\Modelクラスと同様にattach、sync、saveメソッドが追加されました。
Blade::if()句のカスタマイズ
Bladeテンプレートに長いチェックを繰り返し書くと、テンプレートが乱雑になります。Laravel 5.5では、繰り返し実行するチェックを抽象化してテンプレートから分離できるため、テンプレートが読みやすくなります。
@if (auth()->check() && auth()->user()->isSubscribed())
<p>Subscribed</p>
@else
<p>Not Subscribed</p>
@endif
このコードは次のように書き換えられます。
@subscribed
<p>Subscribed</p>
@else
<p>Not Subscribed</p>
@endsubscribed
カスタムBlade句を作成するロジックは、AppServiceProviderクラスのbootメソッドに定義します。
チェックに引数が必要なら、カスタムBlade句を定義するときに、引数をクロージャーに渡します。
@if (auth()->check() && auth()->user()->isFollowing($user->id))
上記の例では、$user->idをisFollowing()メソッドに渡します。$user->idを引数に取るカスタムBlade句は、次のコードで定義します。
Blade::if('following', function (User $user) {
return auth()->check() && auth()->user()->isFollowing($user->id)
});
Bladeをテンプレートで使用します。
@following($user)
<p>Following</p>
@else
<p>Not Following</p>
@endfollowing
新しいArtisanコマンドをカーネルに自動登録する
新しいartisanコマンドを作成するには通常php artisam make:command command-nameを使います。コマンドを実行後に、コマンドのクラスにシグネチャーを宣言し、カーネルに移動して手動でコマンドを登録します。
Laravel 5.5では、コマンドディレクトリを検索してファイルパスをすべてnamespace付きのパスに変換するメソッドがapp/Console/kernel.phpに加わったため、新しいコマンドのカーネル登録が必須ではなくなりました。
[...]
protected function commands()
{
$this->load(__DIR__.'Commands');
require base_path('routes/console.php');
}
[...]
カーネルに登録されていないコマンドを参照しても、commands()メソッドが自動でコマンドを解決します。
新しいRouteメソッド
目玉機能ではありませんが、新しいRouteメソッドが2つ加わりました。
Route::view('/welcome', 'welcome');
Route::redirect('home', 'dashboard');
1つ目のメソッドはwelcome viewを/welcome pathにマップし、2つ目のメソッドは/homeへのリクエストを/dashboardにリダイレクトします。
Laravel Horizonの導入
新しいLaravelのパッケージで、Laravel Redis Queueのダッシュボードとコードで使う設定システムです。
Horizonを使うと、リアルタイムでQueueのワークロード、最近のジョブ、失敗したジョブ、ジョブの再実行、プットやランタイムのメトリックス、プロセス数などの指標で監視できます。
Horizonの機能です。
- ハイレベルなジョブの分析。たとえば、分あたりのジョブ数や過去1時間に実行されたジョブ数
- ジョブとQueueに特化した分析
- タグとモニタリング。ジョブにタグを付けてモニタリングする
- 最近のジョブ。直近に実行したジョブの情報を取得する
- Queueバランス戦略。Queueのワークロードに合わせて自動的にワーカープロセスの負荷を調整する
Horizonの設定や機能はTaylor Otwellの記事に書かれています。私たちもHorizonの記事を書く予定です。
新しいデータベースマイグレーションのトレイト
RefreshDatabaseのトレイトが必要なのか疑問に思う人もいるかもしれませんが、導入された理由には説得力があります。もともと、DatabaseMigrationsとDatabaseTransactionsのトレイトがありました。
テストでDatabaseMigrationsトレイを使うと、テスト前にマイグレーションが実行されたことを保証できます。DatabaseTransactionsトレイトを使うと、テスト後にデータベースが初期状態に復元されたと保証できます。
新しいRefreshDatabaseトレイトは両方の機能を兼ね備えます。テスト開始時にデータベースをマイグレートし、トランザクション付きでテストを実行します。テストのたびにデータベースをマイグレートする必要がなくなり、テストを高速化できます。
最後に
紹介したとおり、魅力的な機能がたくさん追加されました。まだ正式版はリリースされてないので、アップグレードガイドが公開されるまで待ちましょう(日本版編注:8月30日に正式版がリリースされた)。
(原文:What Are the New Features in Laravel 5.5?)
[翻訳:内藤 夏樹/編集:Livit]