Open10

Laravel Weekly Updateまとめ

wadakatuwadakatu

Laravel Weekly Update #1

Laravel Framework / Pipeline ファサード追加

  • Laravel 10.3.0から追加
  • 同じinputに対して、複数の異なるアクションを一気に適用させることができる。
//例 同一ユーザーに対して以下の3つのアクションを行いたい
//・プロフィール写真生成
//・サブスクリプション適用
//・Welcomeメール送付

Pipeline::send($user)
            ->through([
                GenerateProfilePhoto::class,
                ActivateSubscription::class,
                SendWelcomeEmail::class,
            ])
            ->then(fn (User $user) => $user);

Laravel Framework / Channel List コマンド追加

  • php artisan channel:list
  • イベントブロードキャスティングのチャンネル一覧が取得できる

Laravel Forge / ユーザー毎の細かい権限付与

  • Laravel Forgeは、PHPを利用するアプリケーションのサーバーのプロビジョニングや管理を行うツール
  • ユーザー毎の細かい権限付与ができるようになった。
    • サーバー作成とWebサイト作成は許可するけど、それぞれの削除は許可しないなど

Laravel Vapor / 直近のアクティビティ

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • 直近の重要度の高いアクティビティを確認できる画面が追加された
    • いつデプロイを行なったのか
    • キャッシュを削除した

https://www.youtube.com/watch?v=6YvQ_jkfl0c

wadakatuwadakatu

Laravel Weekly Update #2

Laravel Breeze / TypeScript Support

  • Laravel Breezeは、最小限の認証機能を提供するLaravelパッケージ
  • Breezeインストール時に、Blade, Vue, React, APIなどスタックを選ぶことができる
    • VueとReactを選んだ場合に、TypeScriptサポートのON/OFFが選ぶことができる
    • インストールされるTypeScriptのバージョンは「5」

Laravel Valet / Version 4.0 リリース

  • Laravel Valetは、MacOSに特化したLaravel開発環境
    • 約7MBのRAMしか使わないので非常に高速
  • バージョン4で出来ること(一部のみ)
    • valet status(コマンド)
    • nginx, php, homebrewなどの稼働状況が一目でわかる
      -Version 4.0の詳細な情報はこちら

Laravel Forge / サーバー毎に重要なnoteを記述可能

  • Laravel Forgeは、PHPを利用するアプリケーションのサーバーのプロビジョニングや管理を行うツール
  • 管理するサーバー毎に、重要なnoteを書くことができるようになった
    • サーバーの管理者の連絡先を書くなどできる
    • このnoteを観れるのは、各サーバーの権限を持っている人だけ

https://www.youtube.com/watch?v=I44tIi6MM1I

wadakatuwadakatu

Laravel Weekly Update #3

Laravel Framework / Storage::json関数追加

  • この関数を用いてjsonファイルを取得すれば、すぐに配列として使用することができる
// Storage::jsonなしパターン

// ファイル内容を文字列として取得
$contents = Storage::get('my-file.json');
// 取得した文字列をJSONデコードすることで配列に変換
$asArray = json_decode($contents, true);
// Storage::jsonありパターン

//ファイルの内容を配列として取得
$asArray = Storage::json('my-file.json')

Laravel Framework / Relationsにone関数追加

  • HasManyリレーションをHasOneリレーションに簡単に切り替えることが可能
  • 例えば、ECサイトでありがちな以下のようなケース
    • 1ユーザーが持つ複数の契約を取得(HasMany)
    • 1ユーザーが持つ契約の中で、最も金額が高いレコードを取得(HasOne)

今回追加された one関数を利用することで、簡単に上記リレーションを実現できる

// ユーザーが持つ契約を複数取得
public function orders(): HasMany {
    return $this->hasMany(Order::class);
}

// ユーザーが持つ最も金額が高い契約を1つ取得
public function largestOrder(): HasOne {
    return $this->orders()->one()->ofMany('price', 'max');
}

Laravel Vapor / アプリケーションログUI一新

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • アプリケーションログのUIが一新された
    • 文字列検索
    • Lambdaタイプで絞り込み
    • ログタイプ(Info, Error, Debug)で絞り込み
    • 期間での絞り込み
    • 各ログの詳細ページも見やすくなった

https://www.youtube.com/watch?v=1ydSMaoFYz8

wadakatuwadakatu

Laravel Weekly Update #4

Laravel / 大文字、小文字を区別せず値の置き換えが可能(replace関数)

  • replace関数の第三引数が追加された
    • trueを指定することで、大文字、小文字を区別して値を置き換えることが可能(case sensitive / default)
    • falseを指定することで、大文字、小文字を区別せず値を置き換えることが可能(case insensitive)
$result = str('php')->replace('PHP', 'JS');

// case sensitive
echo $result->value;  // 出力結果:php

$result = str('php')->replace('PHP', 'JS', false);

// case insensitive
echo $result->value; // 出力結果: JS

Laravel Pint / PERコーディングスタイル対応

  • Laravel Pintは、PHPコードスタイルの自動整形ツール
  • Laravel Pintのオプション--presetを使うことで、PER Coding Styleに沿った修正が可能
./vendor/bin/pint --preset=per

Laravel Vapor / Queue管理ダッシュボード追加

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • Queueの実行状況を一目で確認できるダッシュボードが追加された
    • 進行中のジョブ
    • 待機中のジョブ
    • 失敗したジョブ
    • 失敗したジョブだけ抜き出して、一覧として表示させることも可能
      • 各ジョブのペイロードやエラーの詳細を確認して、デバッグすることも可能
      • 各ジョブのリトライ / 削除もダッシュボード上で実行可能

https://www.youtube.com/watch?v=T8zKkn77ABk

wadakatuwadakatu

Laravel Weekly Update #5

Laravel Framework / Processファサードにpipeメソッドが追加

  • コマンドをまとめて記述し、同期的に実行することが可能
  • あるコマンドの実行結果を後続のコマンドで使いたい時に便利
use Illuminate\Process\Pipe;
use Illuminate\Support\Facades\Process;
 
$result = Process::pipe(function (Pipe $pipe) {
     // catでファイルの中身を出力
    $pipe->command('cat example.txt');
    // ↑で出力したファイルの中身から「laravel」を検索
    $pipe->command('grep -i "laravel"');
});

Laravel Nova / Tagの事前読み込み機能追加

  • Laravel Nova は、Taylor Otwell氏が作成したLaravel用の管理画面作成パッケージ
  • 特定のタグを事前に読み込み、表示させることが可能
  • 例えば、ユーザーと紐づけるロール設定などを事前に読み込み、簡単に選択できるようにする
// ロールを事前読み込み
Tag::make('roles')->preload();

事前読み込み前

  • 毎回検索欄に文字列を入力し、探す必要がある

事前読み込み後

  • 検索をしなくても、事前読み込みされたロールが一覧に表示される

Laravel Forge / 最新ARM-Basedクラウドサーバーが利用可能

  • Laravel Forgeは、PHPを利用するアプリケーションのサーバーのプロビジョニングや管理を行うツール
  • Hetznerの最新ARM-Basedクラウドサーバーを利用可能
    • パフォーマンスとコストのバランスが良いクラウドサーバー
    • 詳しくは以下のツイートの記事を読んでみると良いかも

Laravel Vapor / 失敗したジョブの一括削除機能追加

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • これまでは、失敗したジョブを1つずつしか削除できなかった
  • ユーザーから上記仕様が不便とフィードバックがあり、全ての失敗ジョブを削除できるように仕様変更

https://www.youtube.com/watch?v=JP4xBO26eSQ

wadakatuwadakatu

Laravel Weekly Update #6

Laravel Framework / ValidatorクラスのAfter関数の改善

  • After関数はデフォルトのバリデーションをクリアした後に、更に追加でバリデーションをかけるために使用する
  • 従来では、追加バリデーションをValidatorインスタンスを渡した無名関数内で記述する
    • しかし、追加バリデーションが複数ある場合や複雑な場合、コード量が多くなり可読性が下がるなどの問題がある
  • そこで、今回After関数に配列を渡すことを可能にした
  • このおかげで、追加バリデーションの記述をより簡潔にわかりやすくできる
    • 配列内には、以下のものを渡すことができる
      • Closure
      • Invokable Class (__invokeメソッドを持つクラス)

After関数内に無名関数を記述する場合(従来)

$validated = Validator::make($request->all(), [
       'title' => 'required|string|max:30',
       'content' => 'required|string|max:100'
  ])->after(function(Validator $validator) {
      // コードが読みづらい
      if(// validation something){
          $validator->errors()->add('title', 'something');
      }else if (// validation something else){
          $validator->errors()->add('content', 'something else')
      }else if (// validation something else else){
          $validator->errors()->add('content', 'something else else');
      }
  })
);

After関数内にcallableの配列を渡す場合(最新)

$validated = Validator::make($request->all(), [
       'title' => 'required|string|max:30',
       'content' => 'required|string|max:100'
  ])->after([
      // 可読性UP
      SomethingValidationRule::class,
      fn(Validator $validator) => // validation for something else 
      function (Validator $validator) {
         // Validation for something else else
      },
  ])
);

Invokable Class

namespace App\Validation;

use Illuminate\Validation\Validator;

class SomethingValidationRule{
    // バリデーションルールをクラス別で分けることができる
    public funciton __invoke(Validator $validator): void{
        if($request->input('title') === 'aho'){
            $validator->errors()->add('title', 'aho is not allowed.');
        }
    }
}

Laravel Framework / PipelineファサードのPipe関数に短縮記法が追加

  • これまでは、Pipeクラスのcommand関数を使用して任意のコマンドを実行していた。
    • 複数コマンドを実行する場合は、$pipe->command('ls -la')を複数個記述する必要があった。
  • しかし、最新のLaravelではPipelineファサードのPipeメソッドの引数に配列で実行したいコマンドを指定するだけで、$pipe->command('ld -la')を複数記述した場合と同じ挙動をするようになった。

短縮記法なし

use Illuminate\Process\Pipe;
use Illuminate\Support\Facades\Process;
 
$result = Process::pipe(function (Pipe $pipe) {
    $pipe->command('cat example.txt');
    $pipe->command('grep -i "laravel"');
});

短縮記法あり

use Illuminate\Support\Facades\Process;
 
$result = Process::pipe([
    'cat example.txt'
    'grep -i laravel'
]);

Laravel Pint / method_chaining_indentationルール追加

  • Laravel Pintは、PHPコードスタイルの自動整形ツール
  • メソッドチェーンを改行した際にインデントがずれている場合、Laravel Pintが自動でインデントを揃えてくれるようになった

before

self::query()
    ->where(hogehoge)
      ->orWhere(hugahuga)
        ->select(humihumi);

Pintコマンド実行

./vendor/bin/pint .

after

self::query()
    ->where(hogehoge)
    ->orWhere(hugahuga)
    ->select(humihumi);

Laravel Vapor / ARMアーキテクチャサポート

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • ARMアーキテクチャを使うことで以下の利点がある
    • 20%のパフォーマンス改善
    • 20%のコスト削減
  • 利用方法は、シンプル
    • vapor.ymlのruntimeに-armの接尾辞をつけた後に、deployするだけ
runtime: php-8.2:al2-arm

https://www.youtube.com/watch?v=Pp_Q_Wmi8JM

wadakatuwadakatu

Laravel Weekly Update #7

Laravel Framework / Middlewareの引数の可読性向上

  • Laravelのmiddlewareには引数を取るパターンと取らないパターンがあります。
    • 引数ありの例
      • throttle:10,1(1分間に10回までアクセスを許可する)
      • auth:admin(admin guardを使ってユーザーがログインしているかをチェック)
    • 引数なしの例
      • auth (web guardを使ってユーザーがログインしているかをチェック)
      • verified(認証済みユーザーであるかをチェック)
  • 初見だと throttle:10,1101が何を示しているのか非常に分かりずらい
  • 上記の問題を解決するために、今回middlewareの静的メソッドが用意されました
    • 静的メソッドには名前付き引数を渡すことができるので、引数の意味が一目でわかりやすい

文字列

Route::middleware(['throttle:10,1'])->group(function(){});

静的メソッド

Route::middleware([ThrottleRequest::with(maxAttempts: 10, decayMinutes: 1);

Laravel Framework / ステータスコードのアサーション用メソッドを3つ追加

  • HTTPリクエストのステータスコードをテストするには、以下の2パターンがある
    • assertStatus()関数の引数に予期されるステータスコードを渡す
      • 例: 200, 403, 404
    • 引数にステータスコードを渡さず、各ステータスコード専用の関数を使う
      • assertOk() === assertStatus(200)
      • assertForbidden() === assertStatus(403)
      • assertNotFound() === assertStatus(404)

今回、後者の方の関数が3つ追加されました

$response->assertGone() // === $response->assertStatus(410)
$resopnse->assertInternalServerError() // === $response->assertStatus(500)
$response->assertServiceUnAvailable() // === $response->assertStatus(503)

https://www.youtube.com/watch?v=t_w3G2qsHic

wadakatuwadakatu

Laravel Weekly Update #8

Laravel Framework / Sleepヘルパー追加

  • PHPのsleep関数のラッパー
  • sleep関数をそのまま使うと、テスト実行時に実際に指定秒数待たないといけない
  • sleepヘルパーを使用することで、そのsleep動作のモックが可能になる
    • 指定秒数待たなくてもテストが可能

PHPのsleep関数

sleep(5)

sleepヘルパー

use Illuminate\Support\Sleep

Sleep::for(5)->seconds(); // sleep(5)と同義

テストで使用できるモックやアサーション

use Illuminate\Support\Sleep

// モック
Sleep::fake();

// アサーション
// Sleep回数(秒数関係なし)
Sleep::assertSleptTimes(1)

// Sleepの内容(複数記述可能)
Sleep::assertSequence([
   Sleep::for(5)->seconds(); // 5秒スリープをしたかどうか
]);

Laravel Forge / カスタムGitリポジトリ使用時にもデプロイ履歴が参照可能

  • Laravel Forgeは、PHPを利用するアプリケーションのサーバーのプロビジョニングや管理を行うツール
  • これまでは、GitHub, GitLab, BitBucket以外のカスタムGitリポジトリを利用している場合、デプロイ履歴の下記情報を確認することができなかった
    • 誰がデプロイしたのか
    • どのブランチを選択したのか
    • コミット識別番号はどれか
  • しかし、今回のアップデートから上記すべての情報を確認することができるようになった

https://www.youtube.com/watch?v=qYZvpvVs6hk

wadakatuwadakatu

Laravel Weekly Update #9

Laravel Framework / Sleepヘルパーにwhenメソッドが追加

  • ある条件がtrueの場合のみ、Sleepを実行したい場合に使用する
  • 条件分岐にif文を書く必要がなく、メソッドチェーンで完結可能
    • コードの可読性向上
  • 以下2つのコードはどちらも同じ挙動をします。
$bool = true;

if($bool){
  Sleep::for(2)->seconds();
}
$bool = true;
Sleep::for(2)->seconds()->when($bool);

Laravel Framework / ULIDからCarbonインスタンスを生成可能

  • ULIDとは
    • Universally Unique Lexicographically Sortable Identifierの略称
    • 26文字の文字列で基本的に構成される(UUIDは36文字)
    • タイムスタンプ + ランダムな文字列で構成される
    • タイムスタンプを持つので、辞書的にソートが可能
    • 詳しいことはこちら
  • 今回、ULIDが持つタイムスタンプからCarbonインスタンスを生成する新しいメソッドが追加された
$ulid = Str::ulid(); // 01ARZ3NDEKTSV4RRFFQ69G5FAV

/** @var Illuminate\Support\Carbon $carbon
$carbon = Carbon::createFromId($ulid);

Laravel Octane / Version2が登場

  • Laravel Octaneは、Open SwooleやSwoole、RoadRunnerなどの高性能なアプリケーションサーバを使用し、アプリケーションを提供することで、アプリケーションのパフォーマンスを向上させます。
  • Version2要件
    • PHPバージョンは8.1以上
    • Laravelバージョンは10.10.1以上
  • RoadRunner側の最新アップデートも含まれており、新しい機能が使えるようになっている。
    • RoadRunnerをゴリゴリ使っている人はかなり便利になるそう。
  • アップグレードガイド

Laravel Vapor / ログ表示画面にDebug Mode搭載

  • Laravel Vapor は、LaravelをAWS Lambda上で動作させることができるツール
  • ログ表示画面に、Debug Modeが搭載された
    • Debug Modeオフの場合、以下のログが画面に表示される
      • アプリケーションログ
    • Debug Modeオンの場合、以下のログが画面に表示される
      • アプリケーションログ
      • サーバー関連ログ
        • PHP-FPM再起動した
        • Laravelのルーティングをキャッシュした
        • etc...

サーバー関連のログに関しては、必要のない場合がほとんどであり、アプリケーションログの方がバグ調査などで重宝します。
デフォルトは、Debug Modeオフになるのでユーザーはアプリケーションログに集中することが可能です。

Debug Modeオフの場合

Debug Modeオンの場合

https://www.youtube.com/watch?v=xd09k3kZOQQ

wadakatuwadakatu

Laravel Weekly Update #10

Laravel FrameWork / Precognition

  • Precognitionとは、バックエンドで記述したルールを用いてリアルタイムでフロントエンドバリデーションができる機能
    • フロントエンド用に同じルールを記載する必要がない
    • フォーム送信する前に、バリデーションエラーがわかるのでUX向上
    • 既存のLaravelアプリケーションに組み込むことも可能

既存のアプリケーションへの組み込み方

1. NPMパッケージインストール

現在使用しているフロントエンドスタックに対応して、Precognitionパッケージをインストールする

# vueのみ
npm install laravel-precognition-vue

# vue + inertia
npm install laravel-precognition-vue-inertia

# reactのみ
npm install laravel-precognition-react

# react + inertia
npm install laravel-precognition-react-inertia

# Alpine + Blade
npm install laravel-precognition-alpine
今回はlaravel-precognition-vue-inertiaをインストールした程で進めていきます。

2. フロントエンド修正

a. useFormのインポート元を変更
- import {useForm} from '@inertiajs/vue3'
+ import {useForm} from 'laravel-precognition-vue-inertia'
b. useFormの書き方変更

- const form = useForm({ // @inertiajs/vue3
+ const form = useForm('post', route('register'), { // laravel-precognition
    name: '',
    email: '',
    password: '',
    password_confirmation: '',
})
c. submitの書き方変更

// @inertiajs/vue3
const form = useform({<--中略-->});

- form.post(route('register'), { // @inertiajs/vue3
+ form.submit({ // laravel-precognition
  onFinish: () => form.reset('password', 'password_confirmation');
})
d. @changeを追加
- <input type="text" v-model="name" required />
+ <input type="text" v-model="name" @change="form.update('name')" required />

3. バックエンド修正

a. Middlewareを追加
web.php
Route::post('/register', [RegisteredUserController::class, 'store'])
+       ->middleware([HandlePrecognitiveRequests::class]);
b. Requestクラスを作成
RegisteredUserController.php
public function store(Request $request){
     // 動作しない ×
    $request->validate([
        'name' => 'required',
        'email' => 'required|email|unique:users',
        'password' => ['required', 'confirmed, Rules\Pasword::default() ]
    ]);
}
UserStoreRequest.php
// 動作する ⚪︎
class UserStoreRequest extends FormRequest{
    public function rules(): array {
        return [
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => ['required', 'confirmed, Rules\Pasword::default() ]
        ]
    }   
}
c. インラインバリデーションを作成したRequestクラスに置き換える
RegisteredUserController.php

- public function store(Request $request){
+ public function store(UserStoreRequest $request){
-    $request->validate([
-       'name' => 'required',
-       'email' => 'required|email|unique:users',
-       'password' => ['required', 'confirmed, Rules\Pasword::default() ]
    ]);
}

4. Live Validationを実行

以上の手順で、リアルタイムでバリデーションが発動するはずです。
Precognitionの更に詳しい情報に関しては、以下の公式サイトを参照してください。
https://laravel.com/docs/10.x/precognition

https://www.youtube.com/watch?v=MVb0hitoG9M