PHPerのための「Laravel 9 について語る」PHPTechCafe

PHPer's NEWS!!

運営維持のために広告をブロックしないでというお願い
ネットの反応を見ると賛否ありそうですが、OSS本体だけでなくこのようなOSS周辺のドキュメントなども今後のありかたや使う側の関わり方を考える時期に来ているのかも。

無料とは思えない充実っぷり

PHP 9.0から、未定義変数をWarning → エラーに変更するRFCが投票中、可決されそう
PHP9 はまだ数年後の話ですが、今からWarningを潰し始めないと大変そう。

ソシャゲの運用を想定して4種類のキャッシュ機構(APCu,OPcache,memcached,Redis)のメモリ枯渇を検証した記事です。
当たり前ですがどのキャッシュ機構を使った場合でもメモリ枯渇を想定してアプリ側の制御や設定値のチューニングをちゃんとしましょうということのようです。

モダンなPHPの機能を使わなくてもPHP5で良いコードが書けることをサンプルコードを交えて紹介されていました。
うん、まあ、でも、できればPHP8にしたいよね。

2000年問題ってありましたね

「Laravel 9」について語り合う

リリースの経緯

  • LTSが消えた件
  • リリースが遅れた件
    • Symfony6.0 が 2021/11/30 リリース
    • Symfony のリリースに合わせるため時期をずらした

新機能について

リリースノート

PHP 8.0

  • Laravel 9 より PHPのサポートバージョンは 8.0.2 以上となった
    • Laravel Sail を利用している場合は docker-compose.json の変更が必要
  • 詳しくは後述のアップデート時のつまづきポイントをチェック

Symfony Mailer

  • Laravel標準のメーラーは Swift Mailer から SymfonyMailer に変更
    • Swift Mailer のメンテナンスが止まっていることが原因
    • Swift MailerSymfony Mailer の互換性はこちらで確認
  • 下位互換性のない変更点がふんだんに含まれているため、利用している場合は要注意

Flysystem 3.x

Storage ファサードによって提供されるファイル操作系処理を強化する Flysystem のバージョンアップ

  • S3、FTP、SFTP などを利用している場合はドライバのアップデートが必要
  • put、write、writeStream の挙動変更 → デフォルトでファイルを上書きするようになる
  • 存在しないファイルを指定すると、例外が返ってくるようになる(以前は null を返していた)
  • その他下位互換性のない変更が含まれているため要注意

Improved Eloquent Accessors / Mutators

Eloquent のアクセサーとミューテタの修正

Laravel 9 以前

public function getNameAttribute($value) { return strtoupper($value); } public function setNameAttribute($value) { $this->attributes['name'] = $value; }

↑ モデルにアクセサーとミューテタにプレフィックス付きのメソッドを定義する必要があった

Laravel 9

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型でキャスト可能

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の定義

enum Category: string { case Fruits = 'fruits'; case People = 'people'; }

ルーティングの記載

Route::get('/categories/{category}', function (Category $category) { return $category->value; });

Forced Scoping Of Route Bindings

親のモデルと子のモデルを使用してRoute model bindingを行いたい場合、子のモデルにはカスタムキーを使用する必要があった。

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を行えるようになった。

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

グループ内のすべてのルートに共通のコントローラを定義できるようになった。

# これまで
# 何度もController名を書かないといけない
use App\Http\Controllers\OrderController;
                    
Route::get('/orders/{id}', [OrderController::class, show]);
Route::post('/orders', [OrderController::class, store]);
# 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 を作成できる
$table->text('bio')->fullText();
  • FULLTEXT INDEX がある列に対して WHERE 句を作成することもできる
$users = DB::table('users')
  ->whereFullText('bio', 'web developer')
  ->get();

Laravel Scout Database Engine

Laravel Scoutデータベースエンジンのサポート

  • Laravel Scout:

Rendering Inline Blade Templates

  • Blade テンプレートファイルではなく、Blade記法の文字列をレンダリングする
  • (どう使うのだろう)
use Illuminate\Support\Facades\Blade;

return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);

Slot Name Shortcut

  • x-slot タグを短く書くことができるようになる

BEFORE

<x-alert>
  <x-slot name="title">
    Server Error
  </x-slot>
                
  <strong>Whoops!</strong> Something went wrong!
</x-alert>

AFTER

<x-slot:title>
  Server Error
</x-slot>

Checked / Selected Blade Directives

Blade に以下のタグが追加

  • @checked
    • チェックボックスをONに指定できる
  • @selected
    • セレクトボックスにてデフォルトで選択されている項目を指定できる
<input type="checkbox" name="active" value="active" @checked(old('active', $user->active)) />
<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" なのね
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 route:list CLI Output

  • route:list の CLI 表示が見やすくなった!

Test Coverage Using Artisan test Command

Soketi Echo Server

Improved Collections IDE Support

  • PGPDocでのジェネリックによる型定義を読み取り、IDEで解釈できるようになる

New Helpers

  • いくつか新しいヘルぱ関数が誕生

アップデートのはまりポイント

Laravel 8 から Laravel 9 へのアップデート

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 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の修正
  • 変更前
    ​​ protected $headers = Request::HEADER_X_FORWARDED_ALL;
  • 変更後
    ​​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 の修正
    • コンテナの再構築
      • sail build --no-cache
    • sail artisan sail:publish でDockerfileをカスタマイズしている場合
      • PHPバージョンの違いにより Laravel 9 へのバージョンアップが通らなくなる可能性がある
      • 一旦、docker-compose.ymllaravel.test コンテナの build 定義を以下の通り修正
        • context: ./vendor/laravel/sail/runtimes/8.1
      • 修正後にDokerfileを差し替えるなどして対応

参考資料

Laravel9 リリースノート

Select a repo