[Laravel] 6.0がリリースされました

Laravelのバージョン6.0がリリースされました。追加された機能について確認します。

LTS Version

Laravelのv6.0は新しいLTSのバージョンです。

Bug Fixesは2021年09月03日、Security Fixesは2022年09月03日までサポートされます。

以前のLTSバージョンであったv5.5については、Bug Fixesは2019年08月30日、Security Fixesは2020年08月30日までとなっています。

また重要な点として、PHPの7.2以上バージョンが必要です。

Releases

リリースノートでは以下のような追加機能が発表されています。

  • 認可レスポンスの改善
  • Job内でのMiddlewareの利用
  • 遅延ロードに対応したコレクション
  • EloquentモデルでSubqueryの利用方法の追加
  • laravel/uiパッケージを利用したフロントエンドのscaffolding

各項目についての詳細を確認します。

認可レスポンスの改善

以前は、ユーザーへの認可処理で拒否された場合に、拒否された内容をカスタムエラーメッセージとして提供することは困難でした。

Laravel 6では、ポリシー内での応答内容を提供するGate::inspect()メソッドが導入されています。

実装方法は、以前のポリシーやGate::define()メソッドの戻り値は真偽値を返す必要がありましたが、Illuminate\Auth\Access\Responseクラスを戻り値として利用します。

/**
 * Determine if the user can view the given flight.
 *
 * @param  \App\User  $user
 * @param  \App\Flight  $flight
 * @return mixed
 */
public function view(User $user, Flight $flight)
{
    return $this->deny('Explanation of denial.');
}

Gate::inspect()メソッドでは以下の通りメッセージの取得が可能で、Gate::allows()メソッドは今まで通り機能します。

$response = Gate::inspect('view', $flight);

if ($response->allowed()) {
    // User is authorized to view the flight...
}

if ($response->denied()) {
    echo $response->message();
}

ルートやコントローラーから$this->authorizeGate::authorizeなどのヘルパーメソッドを使用すると、これらのカスタムメッセージがHTTPステータスコードと共にフロントエンドに自動的に返されます。

Job内でのMiddlewareの利用

ジョブミドルウェアを使用すると、キューに入れられたジョブの実行に関するカスタムロジックをラップして、ジョブ自体の定型的な要素を減らすことができます。

Laravel 6.0では、このロジックをジョブミドルウェアとして抽出し、実行に必要な制限からジョブのハンドルメソッドを解放することができます。

<?php

namespace App\Jobs\Middleware;

use Illuminate\Support\Facades\Redis;

class RateLimited
{
    /**
     * Process the queued job.
     *
     * @param  mixed  $job
     * @param  callable  $next
     * @return mixed
     */
    public function handle($job, $next)
    {
        Redis::throttle('key')
                ->block(0)->allow(1)->every(5)
                ->then(function () use ($job, $next) {
                    // Lock obtained...

                    $next($job);
                }, function () use ($job) {
                    // Could not obtain lock...

                    $job->release(5);
                });
    }
}

ミドルウェアを作成した後、ジョブのmiddleware()メソッドから返すことにより、ミドルウェアをジョブに添付できます。

// Add a middleware method to a job class
public function middleware()
{
     return [new SomeMiddleware];
}

// Specify middleware when dispatching a job
SomeJob::dispatch()->through([new SomeMiddleware]);

遅延ロードに対応したコレクション

遅延ロードに対応するLazyCollectionクラスが追加されて、PHPのジェネレーターを活用して、メモリ使用量を低く抑えながら非常に大きなデータセットを操作できるようになりました。

たとえば、アプリケーションがLaravelのログを解析しながら、数ギガバイトのログファイルを処理する必要があるとします。

ファイル全体を一度にメモリに読み込む代わりに、遅延コレクションを使用して、指定された時間にファイルのごく一部のみをメモリに保持できます。

use App\LogEntry;
use Illuminate\Support\LazyCollection;

LazyCollection::make(function () {
    $handle = fopen('log.txt', 'r');

    while (($line = fgets($handle)) !== false) {
        yield $line;
    }
})
->chunk(4)
->map(function ($lines) {
    return LogEntry::fromLines($lines);
})
->each(function (LogEntry $logEntry) {
    // Process the log entry...
});

また、Eloquentモデルでも同様の遅延ロードが可能になりました。

QueryBuilderのcusror()メソッドを使用することで、LazyCollectionクラスのインスタンスが返却されます。

データベースに対して単一のクエリを実行するだけでなく、一度に1つのEloquentモデルのみをメモリにロードできます。

この例では、実際に10,000人のユーザーが登録済みの場合でも、反復処理するまでフィルターコールバックは実行されず、メモリ使用量を大幅に削減できます。

$users = App\User::cursor()->filter(function ($user) {
    return $user->id > 500;
});

foreach ($users as $user) {
    echo $user->id;
}

EloquentモデルでSubqueryの利用方法の追加

Laravel 6.0では、データベースのサブクエリのサポートにいくつかの新しい機能強化と改善が導入されています。

たとえば、フライトの目的地のテーブルと目的地へのフライトのテーブルがあるとします。フライトテーブルには、目的地にフライトが到着した時間を示すarrived_atカラムがあります。

Laravel 6.0の新しいサブクエリ選択機能を使用すると、1つのクエリを使用して、すべての目的地とその目的地に最後に到着したフライトの名前を選択できます。

return Destination::addSelect(['last_flight' => Flight::select('name')
    ->whereColumn('destination_id', 'destinations.id')
    ->orderBy('arrived_at', 'desc')
    ->limit(1)
])->get();

さらに、クエリビルダーのorderBy()メソッドに追加された新しいサブクエリ機能を使用して、最後のフライトがその目的地に到着した時刻に基づいてすべての目的地を並べ替えることができます。

繰り返しになりますが、これはデータベースに対して単一のクエリを実行中に行うことができます。

return Destination::orderByDesc(
    Flight::select('arrived_at')
        ->whereColumn('destination_id', 'destinations.id')
        ->orderBy('arrived_at', 'desc')
        ->limit(1)
)->get();

laravel/uiパッケージを利用したフロントエンドのscaffolding

Laravelの以前のリリースで通常提供されるフロントエンドの足場は、laravel / ui Composerパッケージに抽出されました。これにより、プライマリフレームワークとは別にファーストパーティUIの足場を開発およびバージョン管理できます。この変更の結果、デフォルトのフレームワークの足場にはBootstrapまたはVueコードが存在せず、フレームワークからmake:authコマンドも抽出されました。

Laravelの以前のリリースに存在する従来のVue / Bootstrap足場を復元するには、laravel / uiパッケージをインストールし、ui Artisanコマンドを使用してフロントエンド足場をインストールします。

以前のLaravelで提供されていたフロントエンドの初期設定はlaravel/uiパッケージに抽出されました。

この変更により、デフォルトのフレームワークの設定にはBootstrapVueが存在せず、フレームワークからmake:authコマンドも抽出されました。

Laravelの以前のリリースに存在する従来のBootstrapVueの初期設定を利用するには、laravel/uiパッケージをインストールし、uiコマンドを使用してインストールします。

composer require laravel/ui

php artisan ui vue --auth

詳しい変更については以下を確認してください。

Release Notes - Laravel - The PHP Framework For Web Artisans

© Xzxzyzyz