弊社で毎月開催し、PHPエンジニアの間で好評いただいている勉強会「PHP TechCafe」。
2022年3月のイベントでは『PHPerのための「Laravel9について語る」』をテーマに語り合いました。
弊社のメンバーがLaravel9の新機能などの情報を元に、他の参加者に意見をいただいて語り合いながらLaravel9について理解を深めました。
今回はその内容についてレポートします。
- PHP TechCafeとは
- PHPerのための「Laravel 9 について語る」
- Laravel9の新機能や変更点
- Symfony Mailer
- Flysystem 3.x
- Improved Eloquent Accessors / Mutators
- Enum Eloquent Attribute Casting
- Implicit Route Bindings With Enums
- Forced Scoping Of Route Bindings
- Controller Route Groups
- Full Text Indexes / WhereClauses
- Slot Name Shortcut
- Checked / Selected Blade Directives
- whereNot clause
- Improved Ignition
- Improved route:list CLI Output
- アップデートの落とし穴
- 編集後記
PHP TechCafeとは
本題に入る前に「PHP TechCafe」について軽く説明します。
「PHP TechCafe」とは弊社が主催しているエンジニア向けのイベントで、エンジニア同士で技術について話し合う憩いの場(カフェ)です。
月に1回開催し、コロナ禍の現在はオンラインで開催しています。
対象者はPHP入門の初級エンジニアからシニアエンジニアを幅広くカバーし、学びの場を提供してエキスパートまでの自己成長を支援することを目的にしています。
「PHP TechCafe」は以下の3部構成です(日によって変わることもあります)。
- ライトニングトーク(LT)
- PHPer's NEWS
- 特集
2022年3月の特集は『PHPerのための「Laravel 9 について語る」』をテーマに開催いたしました。
今回はその中で紹介された内容や盛り上がったポイントをレポートします。
PHPerのための「Laravel 9 について語る」
Laravel9の特徴
まずはお約束のLaravel9の特徴からです。
PHP8対応
PHP8に対応し、8未満には対応しなくなりました。
LTSが消えた
どんどんバージョンを上げていきましょう!、という意味かもしれませんね。
ハイペースなマイナーバージョンアップ
Laravel9は、短いスパンで次々とマイナーバージョンアップを重ねていることにも注目が集まり、話題となりました。
- マイナーバージョンアップで新機能がいくつも追加されています。
- 意外と使えそうな機能もよくあるので、新機能を使いたくなったら上げなきゃいけないですね。
Laravel9の新機能や変更点
Symfony Mailer
Laravel標準のメーラーがSwift MailerからSymfony Mailerに変更されました。
そもそもSwift Mailerってメンテナンスが止まっているのでLaravelもこちらに乗り換えたようです。
- 結構互換性の無いものもあるので、しっかり見て変更しましょう。
- インターフェースも変わってしまったんですね。Classを呼んでるところだけ置き換えたらOKという感じでもないですね。しっかり置き換えないといけない。
Sending Emails with Mailer (Symfony Docs)
Flysystem 3.x
Storageファサードによって提供されており、ファイル操作系処理を強化するFlysystemがバージョンアップしました。
- S3とかFTPなどを利用している場合はドライバのアップデートが必要です。
- 挙動も変わっているんですよね。PutやWrite、Writestreamなどを使うとデフォルトでファイルを上書きするようになるので、注意しないといけないです。
- 存在しないファイルを指定すると以前はNullが返ってきていましたが、例外が返ってくるようになりました。
File Storage Abstraction for PHP - Flysystem
Improved Eloquent Accessors / Mutators
これはEloquentのモデルについてです。
Laravel9 以前
<?php public function getNameAttribute($value) { return strtoupper($value); } public function setNameAttribute($value) { $this->attributes['name'] = $value; }
↑ モデルにアクセサーとミューテタにプレフィックス付きのメソッドを定義する必要がありました。
Laravel9
<?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
PHP8.1以上で稼働させている場合のみ動作して、モデルに挿入する値をEnum型でキャスト可能にします。
<?php use App\Enums\ServerStatus; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'status' => ServerStatus::class, ];
Eloquent:ミューテタ/キャスト 9.x Laravel
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; });
- Enumが使えるようになったから、こういうところにも使っていこうっていうことですかね。
- どこを見たら良いかわかりやすいですね。
- 404にしてくれるのがありがたい。無理やり動かすのは流石につらいので。
Forced Scoping Of Route Bindings
親のモデルと子のモデルを使用してRoute model bindingを行いたい場合、子のモデルにはカスタムキーを使用する必要がありました。
Laravel9 以前
<?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を行えるようになりました。
Laravel9
<?php use App\Models\Post; use App\Models\User; Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post; })->scopeBindings();
- Route model bindingとは、例えばこのコードの場合、RouteパラメータのところにUserやPostやモデル名を指定しています。UserのところにID1が入ったとしたらID1のUserのモデルインスタンスを自動的に取ってきてくれるというものです。
- 今まではカスタムキーで”post:slug”を定義する必要があったのですが、それがLaravel 9からScope Bindingを使えば不要となり、シンプルに書きやすくなったようですね。
Controller Route Groups
全てのルートに共通のコントローラをグループとして定義できるようになりました。
Laravel8
<?php # 何度もController名を書かないといけない use App\Http\Controllers\OrderController; Route::get('/orders/{id}', [OrderController::class, show]); Route::post('/orders', [OrderController::class, store]);
Laravel9
<?php use App\Http\Controllers\OrderController; Route::controller(OrderController::class)->group(function () { Route::get('/orders/{id}', 'show'); Route::post('/orders', 'store'); });
コントローラごとにグループ分けができるようになりました。
この変更にはこんな声がありました。
- ヤンチャな実装する人だったら、まとまりを無視して変なところに定義を書いたりすることがありますが、Laravel9だとそこは強制されるのでヤンチャできなくなりますね。
- 概念としてコントローラが上になったような気がして、個人的にはちょっと嫌だなって思いますね。コントローラがルートを決めたんじゃないかというニュアンスになるので。
- ルートとコントローラが密結合になったんじゃないかという印象を持ちました。ここまでやるならそもそも定義書かなくてよくない?という感じもしますね。
Full Text Indexes / WhereClauses
指定した列に FULLTEXT INDEX を作成できます。※MySQLかPostgreSQL
<?php $table->text('bio')->fullText();
FULLTEXT INDEX がある列に対して、WHERE句を作成することもできます。
<?php $users = DB::table('users') ->whereFullText('bio', 'web developer') ->get();
- これすっごくありがたいです。どデカいテキストの部分一致検索みたいなやつは、巨大掲示板とかになってくると Elasticsearch にするとかでないと対応できなかったんです。PostgreSQLにしろMySQLにしろテーブルとかインデックスの型の定義がすごく独特で大変なんです。しかも標準SQLに定義されていない機能なので正直ダルいんですよ…。だから欲しかった人は本当に欲しかったものだと思います。
- 今まではCreate IndexとかSQLを直書きしないと駄目ですよね。それを検索するときもwhereじゃなくてwhereRawとか使ってSQL直書きするしかなかったんですよ。それが公式にサポートされたから作れるようになったんですね。
Slot Name Shortcut
Blade関連ですね。
X-slotタグを短く書けるようになりました。
Laravel9 以前
<x-alert> <x-slot name="title"> Server Error </x-slot> </x-alert>
Laravel9
<x-slot:title> Server Error </x-slot>
これはサッと読めるようになるので、どんどん使っていきたいですね。
Checked / Selected Blade Directives
こちらもBlade関連。
@checked チェックボックスをONに指定できる
<?php <input type="checkbox" name="active" value="active" @checked(old('active', $user->active)) />
@selected セレクトボックスにてデフォルトで選択されている項目を指定できる
<?php <select name="version"> @foreach ($product->versions as $version) <option value="{{ $version }}" @selected(old('version') == $version)> {{ $version }} </option> @endforeach </select>
- @checkedって書いていたらそこのチェックボックスをオンに出来ますよとか、@selectedにしたらデフォルトで選択されている項目を指定できます。今まで三項演算子で書いていたものがBladeで書けるようになって、痒いところに手が届くようになりました。
whereNot clause
クエリビルダでずっとサポートされていなかった、whereNotがようやく使えるようになりました。
- whereNotは何回かリジェクトされて9.3でやっと取り込まれた経緯があるそうです。
- できることなら肯定形で書きたいです。でもSQLの構文として存在するものはサポートしてほしい気はしますね。今までそれをあえて入れなかったのは、否定形を入れずに綺麗なものを目指すんだという強い意思があったのかもしれないですね。
- SQLの構文としてはあるけど、Laravelには無いから今回取り入れたという感じですかね。あえて書きたいケースもありますし。他のすべてのメソッドにはNotがあるけれど、whereにだけ無いと。
Improved Ignition
開発中の例外発生時などに表示されるIgnitionが新しくなりました。
ダークテーマや「エディタで開く」を選べるようになりました。
Improved route:list CLI Output
route:listのCLIが見やすくなりました。
- 最近CLIの見やすくなるアップデートが割と多いですね。
- 本当に見やすくなりました。ただ一方でPHPUnit Printerに外部ライブラリを入れて綺麗にしていた人は一気に全部崩れたみたいです。なので外して公式にし直すというのがウチではありました。
- 以前は色も何もついてなくて、”…”もついてなくて、縦バーで区切ってましたね。
アップデートの落とし穴
- アップデートガイドのところでここのPHPファイルだけ開いて修正してね、ということです。ここだけ手作業ということで、ハマりそうですね。
app/Http/Middleware/TrustProxies.php の修正
変更前
use Fideveloper\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_POST | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB ;
- Composerをアップデートしてもダメで、Bootstrapのキャッシュを消さなきゃいけないのでこの作業が必要になるようです。
- ここはつまづきますね。「キャッシュ周りでアップデートしたのに何で古い方を読みにいってるの?」ってことが起こってました。
Upgrade Guide - Laravel - The PHP Framework For Web Artisans
編集後記
メジャーバージョンアップだけではなく、マイナーバージョンアップでも次々に機能追加がされたりとさらに開発が活発化している印象でした。
LTSがなくなったのは我々開発者としては痛いところですが、これは長期サポートのコストをLaravelの開発をどんどん前に進めることに充てるというアグレッシブな思想があるからかもしれませんね。
ここでは語りつくせない変更もまだまだあるので、リリースノートは要チェックです。
今後もLaravelの進化から目が離せません!
「PHP TechCafe」では今後もPHPに関する様々なテーマのイベントを企画していきます。
皆さまのご参加をお待ちしております。
connpass.com
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com