owned this note
owned this note
Published
Linked with GitHub
PHPerのための「Laravel 9 について語る」PHPTechCafe
=====================================
# PHPer's NEWS!!
::: info
[PHPフレームワーク「Laravel」のドキュメント翻訳者から広告ブロック使用自粛のお願い](https://opensource.srad.jp/story/22/02/17/1539206/)
:::
運営維持のために広告をブロックしないでというお願い
ネットの反応を見ると賛否ありそうですが、OSS本体だけでなくこのようなOSS周辺のドキュメントなども今後のありかたや使う側の関わり方を考える時期に来ているのかも。
::: info
[一番利用数の多いバージョンはPHP 7.4](https://www.phpexam.jp/2022/02/19/noda-php-news-202202/#php-version-statistics-packagist)
:::
::: info
[実践 Docker - ソフトウェアエンジニアの「Docker よくわからない」を終わりにする本](https://zenn.dev/suzuki_hoge/books/2022-03-docker-practice-8ae36c33424b59)
:::
無料とは思えない充実っぷり
::: info
[【PHP9】ついに未定義変数が使えなくなる](https://qiita.com/rana_kualu/items/7f84fcea5c70248ac99e)
:::
PHP 9.0から、未定義変数をWarning → エラーに変更するRFCが投票中、可決されそう
PHP9 はまだ数年後の話ですが、今からWarningを潰し始めないと大変そう。
::: info
[PHP の各種キャッシュ機構でメモリが枯渇した場合の挙動を調べてみた](https://www.infiniteloop.co.jp/blog/2022/03/php-cache-inspection/)
:::
ソシャゲの運用を想定して4種類のキャッシュ機構(APCu,OPcache,memcached,Redis)のメモリ枯渇を検証した記事です。
当たり前ですがどのキャッシュ機構を使った場合でもメモリ枯渇を想定してアプリ側の制御や設定値のチューニングをちゃんとしましょうということのようです。
::: info
[PHPの改善 !== PHPのバージョンアップ](https://developers.prtimes.jp/2022/03/10/a_nice_php_is_not_equal_as_a_new_php/)
:::
モダンなPHPの機能を使わなくてもPHP5で良いコードが書けることをサンプルコードを交えて紹介されていました。
うん、まあ、でも、できればPHP8にしたいよね。
::: info
[【PHP8.2】false疑似型およびnull型が単独で使えるようになる](https://qiita.com/rana_kualu/items/2ef15cfa2dea8ba0f061)
:::
::: info
[「Chrome 100」リリース 新ロゴやユーザーエージェント対策など](https://www.itmedia.co.jp/news/articles/2203/30/news075.html)
:::
::: info
[2000年問題再来? 間もなくバージョン“100”になるChromeとFirefoxに「リスクあり」とMozillaが警告](https://www.itmedia.co.jp/news/articles/2202/22/news066.html)
:::
2000年問題ってありましたね...
::: info
[プロフェッショナルWebプログラミング Laravel〈最新Laravel 9対応〉](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%ABWeb%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Laravel%E3%80%88%E6%9C%80%E6%96%B0Laravel-9%E5%AF%BE%E5%BF%9C%E3%80%89-%E4%B9%85%E4%BF%9D%E7%94%B0-%E8%B3%A2%E4%BA%8C%E6%9C%97/dp/4295202835)
:::
# 「Laravel 9」について語り合う
## リリースの経緯
* LTSが消えた件
* リリースが遅れた件
* Symfony6.0 が 2021/11/30 リリース
* Symfony のリリースに合わせるため時期をずらした
## 新機能について
### リリースノート
* 英語版
* https://laravel.com/docs/9.x/releases
* 日本語版
* https://readouble.com/laravel/9.x/ja/releases.html
### PHP 8.0
* Laravel 9 より PHPのサポートバージョンは `8.0.2` 以上となった
* Laravel Sail を利用している場合は `docker-compose.json` の変更が必要
* 詳しくは後述のアップデート時のつまづきポイントをチェック
### Symfony Mailer
* Laravel標準のメーラーは `Swift Mailer` から `SymfonyMailer` に変更
* `Swift Mailer` のメンテナンスが止まっていることが原因
* `Swift Mailer` と `Symfony Mailer` の互換性は[こちら](https://laravel.com/docs/9.x/upgrade#symfony-mailer)で確認
* 下位互換性のない変更点がふんだんに含まれているため、利用している場合は要注意
### Flysystem 3.x
`Storage` ファサードによって提供されるファイル操作系処理を強化する [`Flysystem` のバージョンアップ](https://laravel.com/docs/9.x/upgrade#flysystem-3)
* S3、FTP、SFTP などを利用している場合はドライバのアップデートが必要
* put、write、writeStream の挙動変更 → デフォルトでファイルを上書きするようになる
* 存在しないファイルを指定すると、例外が返ってくるようになる(以前は null を返していた)
* その他下位互換性のない変更が含まれているため要注意
### Improved Eloquent Accessors / Mutators
Eloquent の[アクセサーとミューテタ](https://readouble.com/laravel/7.x/ja/eloquent-mutators.html)の修正
**Laravel 9 以前**
```php=
public function getNameAttribute($value)
{
return strtoupper($value);
}
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
}
```
↑ モデルにアクセサーとミューテタにプレフィックス付きのメソッドを定義する必要があった
**Laravel 9**
```php=
use Illuminate\Database\Eloquent\Casts\Attribute;
public function name(): Attribute
{
return new Attribute(
get: fn ($value) => strtoupper($value),
set: fn ($value) => $value,
);
}
```
↑ プレフィックスなしのメソッドに戻り値の型を指定(Attribute)することでアクセサーとミューテタが定義可能
### Enum Eloquent Attribute Casting
※ PHP 8.1 で稼働させている場合のみ動作
モデルに挿入する値をEnum型でキャスト可能
```php=
use App\Enums\ServerStatus;
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'status' => ServerStatus::class,
];
```
### Implicit Route Bindings With Enums
* ルートパラメータをEnum型で型指定することができる
* 型に一致しないパラメータが指定された場合は 404 が返される
**Enumの定義**
```php=
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}
```
**ルーティングの記載**
```php=
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});
```
### Forced Scoping Of Route Bindings
親のモデルと子のモデルを使用してRoute model bindingを行いたい場合、子のモデルにはカスタムキーを使用する必要があった。
```php
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
```
scopeBindings()を使用することで、カスタムキーなしでも子のモデルに対してRoute model bindingを行えるようになった。
```php
use App\Models\Post;
use App\Models\User;
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();
```
### Controller Route Groups
グループ内のすべてのルートに共通のコントローラを定義できるようになった。
```php
# これまで
# 何度もController名を書かないといけない
use App\Http\Controllers\OrderController;
Route::get('/orders/{id}', [OrderController::class, show]);
Route::post('/orders', [OrderController::class, store]);
```
```php
# laravel9~
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
```
### Full Text Indexes / Where Clauses
* MySQLかPostgreSQLで利用可能
* 指定した列に FULLTEXT INDEX を作成できる
```php
$table->text('bio')->fullText();
```
* FULLTEXT INDEX がある列に対して WHERE 句を作成することもできる
```php
$users = DB::table('users')
->whereFullText('bio', 'web developer')
->get();
```
### Laravel Scout Database Engine
Laravel Scoutデータベースエンジンのサポート
* Laravel Scout:
### Rendering Inline Blade Templates
* Blade テンプレートファイルではなく、Blade記法の文字列をレンダリングする
* (どう使うのだろう...)
```php
use Illuminate\Support\Facades\Blade;
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
```
### Slot Name Shortcut
* `x-slot` タグを短く書くことができるようになる
**BEFORE**
```html
<x-alert>
<x-slot name="title">
Server Error
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
```
**AFTER**
```html
<x-slot:title>
Server Error
</x-slot>
```
### Checked / Selected Blade Directives
Blade に以下のタグが追加
* @checked
* チェックボックスをONに指定できる
* @selected
* セレクトボックスにてデフォルトで選択されている項目を指定できる
```html=
<input type="checkbox"
name="active"
value="active"
@checked(old('active', $user->active)) />
```
```html=
<select name="version">
@foreach ($product->versions as $version)
<option value="{{ $version }}" @selected(old('version') == $version)>
{{ $version }}
</option>
@endforeach
</select>
```
### Bootstrap 5 Pagination Views
* Bootstrap 5 のページネーションを利用できるようになる
* 以下の通り記述することで使用できる
* "useBootstrap5" ではなく "useBootstrapFive" なのね
```php=
use Illuminate\Pagination\Paginator;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Paginator::useBootstrapFive();
}
```
### Improved Validation Of Nested Array Data
### Laravel Breeze API & Next.js
### Improved Ignition Exception Page
* 開発中の例外発生時やデバッグ時に表示される Ignition が新しくなった模様
* ダークテーマ / "エディタで開く" のカスタマイズなど
### Improved <code>route:list</code> CLI Output
* `route:list` の CLI 表示が見やすくなった!
### Test Coverage Using Artisan <code>test</code> Command
### Soketi Echo Server
### [Improved Collections IDE Support](https://laravel.com/docs/9.x/releases#improved-collections-ide-support)
* PGPDocでのジェネリックによる型定義を読み取り、IDEで解釈できるようになる
* ![](https://i.imgur.com/zFAOqTQ.png)
### New Helpers
* いくつか新しいヘルぱ関数が誕生
## アップデートのはまりポイント
### Laravel 8 から Laravel 9 へのアップデート
* [アップデート手順](https://laravel.com/docs/master/upgrade)
#### composer.json の更新
* laravel/framework
* ^9.0
* nunomaduro/collision
* ^6.1
* facade/ignition
* "spatie/laravel-ignition": "^1.0"
上記の通り変更して `composer update` を行う
**おすすめポイント**
* Laravel 9 以降は PHP のバージョンが `8.0.2` 以上である必要があるが、ローカルPC側の PHP のバージョンが `8.1` まで上がってしまっていると composer update が失敗してしまう
* [Docker の composer](https://hub.docker.com/_/composer) を利用する
```
docker run --rm --interactive --tty \
--volume $PWD:/app \
composer update
```
#### プログラム修正
##### app/Http/Middleware/TrustProxies.php の修正
###### use の変更
* 変更前
* use Fideloper\Proxy\TrustProxies as Middleware
* 変更後
* use Illuminate\Http\Middleware\TrustProxies as Middleware
###### `$headers`の修正
* 変更前
```php=
protected $headers = Request::HEADER_X_FORWARDED_ALL;
```
* 変更後
```php=
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
```
#### Laravel Sail を利用している場合
`docker-compose` に記載しているPHPバージョンの変更が必要
* [docker-compose の修正](https://readouble.com/laravel/8.x/ja/sail.html#sail-php-versions)
* コンテナの再構築
* `sail build --no-cache`
* `sail artisan sail:publish` でDockerfileをカスタマイズしている場合
* PHPバージョンの違いにより Laravel 9 へのバージョンアップが通らなくなる可能性がある
* 一旦、`docker-compose.yml` の `laravel.test` コンテナの build 定義を以下の通り修正
* context: ./vendor/laravel/sail/runtimes/8.1
* 修正後にDokerfileを差し替えるなどして対応
<!-- * 下位互換性のない変更
* sail を使っている場合、使っていない場合の違いなど
-->
# 参考資料
[Laravel9 リリースノート](https://laravel.com/docs/9.x/releases)