Laravel 10を見学する
Laravel 10を見学する
こんばんは。エンジニアの山下です。
Laravel 10が2023年2月14日にリリースされたので、その内容をリリースノートを追いながら確認します。
サポート
まずver10とその前後のサポート期間については以下の通りです。 (https://laravel.com/docs/10.x/releases#support-policy より引用)
Version | PHP version | Release | バグ修正対応期間 | セキュリティ修正対応期間 |
---|---|---|---|---|
8 | 7.3-8.1 | 2020年9月8日 | 2022年7月26日 | 2023年1月24日 |
9 | 8.0-8.1 | 2022年2月8日 | 2023年8月8日 | 2024年2月6日 |
10 | 8.1-8.2 | 2023年2月14日 | 2024年8月6日 | 2025年2月4日 |
既にver8はメンテナンスの対象外ですね、時の流れ恐るべしです。
また、ver10の動作に必要なPHPのバージョンは8.1-8.2なので、今回のデモではphp8.2.4を使用します。
型・タイプヒントの強化
https://laravel.com/docs/10.x/releases#types
updates the application skeleton and all stubs utilized by the framework to introduce argument and return types to all method signatures. In addition, extraneous "doc block" type-hint information has been deleted.
「application skeleton」と「stubs」はおそらく、Laravelが自動で生成してくれるコード群のことをさしています。
「php artisan xxx」で生成されるようなコードにも、以前に増して型情報を定義してくれるようです。
リポジトリのdiffで修正内容を見ると確認できるのですが、確かに引数や返り値に対して型が指定されている箇所が多く見られ、application skelton and all stubs ...と記載されている通り、.stubファイルにも型に関する修正が確認できます。
PHP8.xへの対応
リリースノートには記載がないのですが、PHP8への対応は押さえておきます。コーディングする際のお手本として、特に新しい書き方へ移行する修正方法・書き方はキャッチアップしておきたいです。
catch()の変数を省略
- https://github.com/laravel/framework/compare/v9.52.4...v10.4.1#diff-14a15185e5dabb6621c27ded8fda4891a78b857b0872e46d52c3dacce6457564L877
- https://github.com/laravel/framework/compare/v9.52.4...v10.4.1#diff-94fc5521c4c3013979aa52c1d6d5dad652e6e10467b7e45481736d3c986e099fL559
この修正はかなり多く目にします。
PHP8.0からはcatchの変数を省略することができます。
// before
try {} catch(Throwable $e) {}
// after
try {} catch(Throwable) {}
protected → public readonly
readonlyはPHP8.1以降で使える宣言の仕方で、プロパティが初期化後に変更されないようにすることができます。
変更の経緯ですが、クラスの外からprotected $nameそのものを取得したいという要望が発端で、一時はgetterとしてpublic getGuardName()の実装も検討されますが、結果publicをprotectedに変更しreadonlyが付与されました。
class SessionGuard implements StatefulGuard, SupportsBasicAuth {
// before
protected $name
// after
public readonly $name
public function __construct($name,
/*引数省略*/
)
{
$this->name = $name;
//以下省略
}
/**
* Get a unique identifier for the auth session value.
*
* @return string
*/
public function getName()
{
return 'login_'.$this->name.'_'.sha1(static::class);
}
/**
* Get the name of the cookie used to store the "recaller".
*
* @return string
*/
public function getRecallerName()
{
return 'remember_'.$this->name.'_'.sha1(static::class);
}
}
array_is_listの使用
PHP8.1以降で使える関数で、名前の通り配列がリストかどうかを確認します。
ここでいうリストとは、キーが数値の0から順番に並んでいる配列(連想配列)のことです。
print_r(['a', 'b', 'c']);
/*
Array
(
[0] => a
[1] => b
[2] => c
)
*/
array_is_list(['a', 'b', 'c']);
// true
array_is_list(['0'=>'a','1'=> 'b','2'=> 'c']);
// true
// '0'は0に変換されます。
Laravelの話に戻りますが、array_is_listは\Illuminate\Collections\Arr::isAssoc()の代替として使われており、isAssoc自体もまだ存在しています。(実際にはarray_is_listの否定がisAssoc)
public static function isAssoc(array $array)
{
// before
$keys = array_keys($array);
return array_keys($keys) !== $keys;
// after
return ! array_is_list($array);
}
元々の実装も良いですね。
また、isAssocからarray_is_listへの変更も確認できます。 https://github.com/laravel/framework/compare/v9.52.4...v10.4.1#diff-770e6afc4f120d519e68c9f0b8de5fc5694eb0bc558b52f7464db8d9bf10e50fL458
attribute
PHP8.0以降で使えるアトリビュートも発見しました。
Illuminate\Cache\Console\PruneStaleTagsCommandにattributeがついています。
$command = new \Illuminate\Cache\Console\PruneStaleTagsCommand();
(new ReflectionClass($command))->getAttributes();
/*
[
ReflectionAttribute {#3739
name: "Symfony\Component\Console\Attribute\AsCommand",
arguments: [
"name" => "cache:prune-stale-tags",
],
},
]
*/
プロパティの$nameと$descriptionを削除して、attributeを変更してみます。
#[AsCommand(name: 'cache:TEST', description: 'hello, i\'m in attribute')]
class PruneStaleTagsCommand extends Command
{}
bashから「php artisan list」でコマンドの一覧を確認すると、指定した内容が表示されています。 diffを読むのはこの辺にしておいて、リリースノートに戻ります。
Laravel Pennant
https://laravel.com/docs/10.x/releases#laravel-pennant
新しいファーストパーティのパッケージ「Laravel Pennant」(以下Pennant)が追加されたようです。
アプリケーションの機能を管理するようなことが出来るらしく、例えば...新しく実装した機能をとりあえず有料課金ユーザだけが使用できるようにして、だんだんとロールアウトするようなケースで有効のようです。
Process操作
https://laravel.com/docs/10.x/releases#process
Symfony Processを優しくラップして包み込み、テストのためのFake,Mock機能を提供しています。
Facadeとして公開されているので、Process::run('any-command')
とするだけでコマンドが実行できます。
さらにProcess::forever()
の返り値Illuminate\Process\PendingProcessにはTTYモードがあり、tinkerからvimを開くこともできるようです。
非同期(バックグラウンド)で処理をするにはProcess::start('any-command')
とするだけです。
tinkerで試してスクショしました。start()を呼び出した直後に次のコマンドが入力可能になり、running()ではプロセスが終了したかどうかを確認しています。
artisan makeコマンドに対話モード追加
https://laravel.com/docs/10.x/releases#generator-cli-prompts
「あれmake:modelって引数何だっけ...」はあるあるかと思いますが、そんな時はartisan make:model
とだけ入力すればオプションの値をコマンドから質問されるようになりました。
百聞は一見にしかずですね。nodeのcreate-react-appを思い出します。
Test Profiling
https://laravel.com/docs/10.x/releases#test-profiling
artisan test
へ--profile(引数なし)オプションが追加されました。
各テストに掛かる時間を表示してくれるようなので、軽くテストを書いて試してみます。せっかくなのでProcessを使ってSleepを呼びます。
// routes/api.php
Route::group(['namespace' => 'sleep'], function() {
Route::get('/wait/:t', fn(int $t) => Process::run("sleep $t"));
Route::get('/async/:t', fn(int $t) => Process::start("sleep $t"));
});
// tests/Feature/SleepTest.php
public function test_wait_1(): void
{
$response = $this->get('/api/wait/1');
$this->assertTrue(true);
}
public function test_wait_5(): void
{
$response = $this->get('/api/wait/5');
$this->assertTrue(true);
}
public function test_async_1(): void
{
$response = $this->get('/api/async/1');
$this->assertTrue(true);
}
public function test_async_5(): void
{
$response = $this->get('/api/async/5');
$this->assertTrue(true);
}
php artisan test --profile
を実行すると、Top 10 slowest tests:
と題して遅いテストランキングが表示されています。
その他
その他にもプロジェクト作成時にテストライブラリPestの導入をするためのコマンドオプションや開発環境のモニタリングツールTelescopeとキュー、ワーカに特化したモニタリングツールHorizonのUIが刷新され、よりモダンになったようです。
詳しくはリリースノートを確認してみてください。
Webサイト・システムの
お悩みがある方は
お気軽にご相談ください
出張またはWeb会議にて、貴社Webサイトの改善すべき点や
ご相談事項に無料で回答いたします。