[Laravel] 5.8がリリースされました
laravel/frameworkのバージョン5.8がリリースされました。追加された機能について確認します。
Release
Eloquent
クラスにHasOneThrough()
メソッドが追加されました
関連するリレーションを経由したリレーションを操作できます。
たとえば、Supplier
モデルにAccount
モデルが1つあり、Account
モデルにAccountHistory
モデルが1つあるとします。
Account
モデルを通じてSupplier
のAccountHistory
を1件するには、hasOneThrough
リレーションを使用します。
Schema:
// suppliers table
Schema::create('suppliers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
// accounts table
Schema::create('accounts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('supplier_id');
$table->string('email');
$table->timestamps();
});
// account_histories table
Schema::create('account_histories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('account_id');
$table->string('sentence');
$table->timestamps();
});
hasOneThrough Model:
// App\Supplier class
/**
* Get the account history for the supplier.
*/
public function accountHistory()
{
return $this->hasOneThrough(AccountHistory::class, Account::class);
}
$supplier->accountHistory;
Result:
{
"id": 1,
"account_id": 1,
"content": "Officia quas velit minus explicabo quibusdam a.",
"created_at": "2019-02-27 01:52:21",
"updated_at": "2019-02-27 01:52:21",
"laravel_through_key": 1
}
// select * from `suppliers` where `suppliers`.`id` = 1 limit 1
// select `account_histories`.*, `accounts`.`supplier_id` as `laravel_through_key` from `account_histories` inner join `accounts` on `accounts`.`id` = `account_histories`.`account_id` where `accounts`.`supplier_id` = 1 limit 1
また、Supplier
の全てのAccountHistory
を取得する場合にはhasManyThrough()
リレーションを使用します。
hasManyThrough Model:
// App\Supplier class
/**
* Get the account histories for the supplier.
*/
public function accountHistories()
{
return $this->hasManyThrough(AccountHistory::class, Account::class);
}
$supplier->accountHistories;
Result:
[
{
"id": 1,
"account_id": 1,
"content": "Officia quas velit minus explicabo quibusdam a.",
"created_at": "2019-02-27 01:52:21",
"updated_at": "2019-02-27 01:52:21",
"laravel_through_key": 1
},
{
"id": 2,
"account_id": 2,
"content": "Qui ut optio est voluptatem dolores voluptatem tempore.",
"created_at": "2019-02-27 01:52:21",
"updated_at": "2019-02-27 01:52:21",
"laravel_through_key": 1
},
...
{
"id": 201,
"account_id": 1,
"content": "Qui odio excepturi magni est quisquam.",
"created_at": "2019-02-27 01:52:22",
"updated_at": "2019-02-27 01:52:22",
"laravel_through_key": 1
},
{
"id": 202,
"account_id": 2,
"content": "Sed nesciunt architecto est voluptas officiis esse voluptatem.",
"created_at": "2019-02-27 01:52:22",
"updated_at": "2019-02-27 01:52:22",
"laravel_through_key": 1
}
]
// select * from `suppliers` where `suppliers`.`id` = 1 limit 1
// select `account_histories`.*, `accounts`.`supplier_id` as `laravel_through_key` from `account_histories` inner join `accounts` on `accounts`.`id` = `account_histories`.`account_id` where `accounts`.`supplier_id` = 1
モデルのPolicy
が自動検出されるようになりました
v5.7までのPolicy
の利用にはAuthServiceProvider
への手動登録が必要でしたが、v5.8からは自動で登録されるようになります。
自動登録を行うには、クラス名をモデル名 + Policy
とし、app/policies
ディレクトリへ配置するという命名規則に従う必要があります。
また、独自の命名規則を使用する場合にはGate
クラスのguessPolicyNameUsing()
メソッドを利用して拡張することができます。
// app/Providers/AuthServiceProvider.php
public function boot()
{
$this->registerPolicies();
Gate::guessPolicyNameUsing(function ($modelClass) {
$policyClass = class_basename($modelClass) . 'Authorizer';
return "App\\Policies\\{$name}";
});
}
Cache
の仕様がPSR-16
に準拠されました
以下のキャッシュメソッドに渡していた整数の引数の値が分数
から秒数
へ変更されました。
- put
- putMany
- add
- remember
- setDefaultCacheTime
引数としてDateTime
クラス(Carbon
クラス等の拡張クラス含む)を渡している場合には変更はありません。
// Laravel 5.7 - Store item for 30 minutes...
Cache::put('foo', 'bar', 30);
// Laravel 5.8 - Store item for 30 seconds...
Cache::put('foo', 'bar', 30);
// Laravel 5.7 / 5.8 - Store item for 30 seconds...
Cache::put('foo', 'bar', now()->addSeconds(30));
Broadcast
に複数の認証が指定可能になりました
以前のリリースでは、BroadcastChannel
はアプリケーションのデフォルト認証を介してユーザを認証していました。
Laravel 5.8以降では、通知要求を認証するための複数の認証を割り当てることができます。
Broadcast::channel('channel', function() {
// ...
}, ['guards' => ['web', 'admin']])
API Tokenの認証にSHA256ハッシュのサポートが追加されました
プレーンテキストTokenを格納するよりもセキュリティが向上します。
利用するにはconfig/auth.php
でhash
の利用を許可します。
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => true,
],
また、API Tokenの作成はユーザー登録時には行わず、アプリケーション内に独自のAPIトークン管理ページを実装する必要があります。
このページでは、ユーザーが自分のAPI Tokenを初期化して更新できるようにする必要があります。
ユーザーのTokenの初期化または更新が必要な場合は、Tokenのハッシュコピーをデータベースに格納し、Tokenのプレーンテキストコピーを一度表示するためにクライアントに返す必要があります。
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
class ApiTokenController extends Controller
{
/**
* Update the authenticated user's API token.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function update(Request $request)
{
$token = Str::random(60);
$request->user()->forceFill([
'api_token' => hash('sha256', $token),
])->save();
return ['token' => $token];
}
}
メールアドレスに対するバリデーションが改善されました
Schedule
を実行するタイムゾーンの指定が可能になりました
timezone()
メソッドを使ってスケジュールされたタスクのタイムゾーンを指定できます。
$schedule->command('inspire')
->hourly()
->timezone('America/Chicago');
また、すべてのスケジュールされたタスクに対して同じタイムゾーンを指定する場合には、\App\Console\Kernel
クラスのscheduleTimezone()
メソッドを利用して一律に設定が可能です。
/**
* Get the timezone that should be used by default for scheduled events.
*
* @return \DateTimeZone|string|null
*/
protected function scheduleTimezone()
{
return 'America/Chicago';
}
Pivot
モデルの更新時にEloquent
モデルイベントが発行されうようになりました
Artisan
クラスのcall()
メソッドの引数問題が改善されました
Laravelの以前のリリースでは、コマンドのオプションはメソッドの2番目の引数として配列を介して渡されていました。
use Illuminate\Support\Facades\Artisan;
Artisan::call('migrate:install', ['database' => 'foo']);
しかし、Laravel 5.8では、オプションを含むコマンド全体をメソッドの最初の文字列引数として渡すことができます。
Artisan::call('migrate:install --database=foo');
テスト時のMock
、Spy
に関するヘルパーメソッドが追加されました
モックオブジェクトをより便利にするために、新しいモックメソッドとスパイメソッドが基本のLaravelテストケースクラスに追加されました。
これらのメソッドは、モッククラスを自動的にコンテナにバインドします。
// Laravel 5.7
$this->instance(Service::class, Mockery::mock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
}));
// Laravel 5.8
$this->mock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
});
Resources
クラスを利用してDatabaseCollection
のレスポンスを行う際にkeyをカスタマイズできるようになりました
コレクションのキーを保存するかどうかを示すpreserveKeys
プロパティをリソースクラスに追加できるようになりました。
デフォルトでは、そして以前のLaravelリリースとの一貫性を保つために、キーはデフォルトでリセットされます。
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class User extends JsonResource
{
/**
* Indicates if the resource's collection keys should be preserved.
*
* @var bool
*/
public $preserveKeys = true;
}
preserveKeys
プロパティが未設定の場合には、コレクションキーは保持されます。
use App\User;
use App\Http\Resources\User as UserResource;
Route::get('/user', function () {
return UserResource::collection(User::all()->keyBy->id);
});
Eloquent
モデルのorWhere()
メソッドがHigherOrder
に対応しました
Laravelの以前のリリースでは、論理和演算子を介して複数のEloquentモデルスコープを組み合わせるには、Closureコールバックを使用する必要がありました。
// scopePopular and scopeActive methods defined on the User model...
$users = App\User::popular()->orWhere(function (Builder $query) {
$query->active();
})->get();
Laravel 5.8では、クロージャを使用せずにこれらのスコープをスムーズに連鎖させることができるHigherOrder
なorWhere
メソッドが導入されました。
$users = App\User::popular()->orWhere->active()->get();
Artisan Serve
コマンドでのビルドインサーバーを複数起動可能になりました
Laravelの以前のリリースでは、Artisanのserve
コマンドはポート8000
でビルドインサーバーを提供していました。
別のアプリケーションでserve
コマンドを実行した場合には、既にポートがlistenされているため、コマンドはエラーを投げていました。
Laravel 5.8以降、serve
はポート8009
までの使用可能なポートをスキャンするようになりました。これにより、一度に複数のアプリケーションに対応できます。
Blade
ファイルへの追跡が可能になりました
Blade
テンプレートをコンパイルするとき、Laravelはコンパイル済みファイルの先頭に元のBlade
テンプレートへのパスを含むコメントを追加するようになりました。
Cache
、Session
のドライバにDynamoDB
が利用可能になりました
DynamoDB
をドライバとして利用する場合にはconfig/cache.php
を設定します。
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
],
Carbon 2.0がサポートされました
Pheanstalk 4.0がサポートされました
Upgrade
MySQLでJson型のカラムの結果を受け取る場合に引用符が付与されなくなりました
MySQLとMariaDBを使用している場合、クエリービルダーは引用符で囲まれていないJSON値を返すようになりました。
この動作は、サポートされている他のデータベースと一貫性があります。
その結果、 ->>`演算子はサポートされなくなり、必要なくなりました。
$value = DB::table('users')->value('options->language');
dump($value);
// Laravel 5.7...
'"en"'
// Laravel 5.8...
'en'
Illuminate/Events/Dispatcher
クラスのfire()
メソッドが削除されました
代わりにdispatch()
メソッドを使用してください。
SoftDelete
を利用したモデルのdeleted_at
カラムがキャストされるようになりました
Eloquent
モデルがSoftDeletesト
レイトを使用するとき、deleted_at
プロパティは自動的にCarbon
インスタンスにキャストされます。
この動作を無効にするには、そのプロパティのカスタムアクセサを作成するか、手動でcasts属性に追加します。
protected $casts = ['deleted_at' => 'string'];
MarkDownメールのファイルディレクトリが変更されました
/resources/views/vendor/mail/markdown
へ変更されました。
以前にvendor:publish
を実行してファイルをコピーしている場合には手動で変更する必要があります。
str_*
およびarray_*
に関するヘルパーが非推奨になりました
これらのヘルパーは削除される予定なので、代わりにIlluminate\Support\Arr
およびIlluminate\Support\Str
クラスを使用してください。
ヘルパーが必要な場合は、laravel/helpersパッケージを追加でインストールしてください。
Nexmo
およびSlack
への通知クラスが外部パッケージへと変更されました
アプリケーションでこれらのチャンネルを使用するには、以下のパッケージが必要です。
composer require laravel/nexmo-notification-channel
composer require laravel/slack-notification-channel
詳しい変更については以下を確認してください。
Release Notes - Laravel - The PHP Framework For Web Artisans