🔖

Laravelの`when()`ヘルパーで条件分岐をスマートに書く

2025/02/26に公開

こんにちは。今回は、Laravel 12以降で使えるようになった when() ヘルパーを活用して、条件分岐をシンプルに書く方法を紹介します。コードの可読性を高めたい方や、複雑な if 文や三項演算子に悩んでいる方は必見です。


when() ヘルパーとは?

when() ヘルパーは、引数の値やクロージャの戻り値が「真(truthy)」か「偽(falsy)」かで、返す値を分岐させるためのLaravelの関数です。Laravelのコレクションメソッドなどでお馴染みの when() と似たような使い方ができ、コードを簡潔にまとめられます。

従来の if-else との違い

例えば従来の書き方だと、次のような if-else を書いていたかもしれません。

$shippingCost = 0;

if ($region === 'EU') {
    $shippingCost = 15;
} else {
    $shippingCost = 25;
}

これでも問題はありませんが、条件分岐が多くなるとコードが見づらくなる可能性があります。when() を使えば、以下のようにまとめることができます。


実際のサンプルコード

以下の例では、送料配達日when() を使って決定しています。

// 💡 Laravelのヒント: when() ヘルパーを使って条件分岐をシンプルに! 

$shippingCost = when(
    $region === 'EU',
    fn() => 15, // ヨーロッパなら15ドルの送料
    fn() => 25  // それ以外は25ドル
);

// ✨ Laravel 12以降: when() はクロージャを条件に使えるようになった!

$deliveryDate = when(
    fn() => $customer->isPremium() && today()->isWeekend(),
    fn() => today()->addDays(7), // プレミアム会員は週末なら7日追加
    fn() => today()->addDays(3)  // 通常会員は3日追加
);

// [もし理解できなくても気にしないでOK!]

それぞれのポイント

  1. $shippingCost の決定
    $region'EU' かどうかで分岐しています。ヨーロッパなら送料が15ドル、それ以外は25ドルというシンプルな条件です。

  2. $deliveryDate の決定

    • fn() => $customer->isPremium() && today()->isWeekend() というクロージャを条件として使っています。これは「プレミアム会員 かつ 週末である」場合に true となるので、返す値は today()->addDays(7)
    • 条件に合致しなければ today()->addDays(3) になります。
    • when() の第一引数にクロージャを指定すると、戻り値が truefalse で条件が判定されます。

when() ヘルパーの基本的な使い方

when() ヘルパーは、次のようなシグネチャになっています。

when(
    bool|Closure $condition,
    Closure|mixed $valueIfTrue,
    Closure|mixed|null $valueIfFalse = null
)
  • $condition
    真偽値か、あるいは真偽値を返すクロージャを渡します。
  • $valueIfTrue
    $condition が true の場合に返される値。クロージャか直接の値のどちらもOKです。
  • $valueIfFalse
    $condition が false の場合に返される値。こちらもクロージャか直接の値を渡せます。

これによって、if-else のブロックを一行や数行でまとめることができます。ネストした条件分岐が増えてしまう場合や、変数への代入が複雑になりがちな時に有用です。


注意点

  • when() は Laravel 8〜9 でもコレクションメソッドとして存在しましたが、Laravel 12以降ではより柔軟に使えるようになっています。プロジェクトのバージョンに合わせて使えるかどうか確認しましょう。
  • 可読性が上がる反面、複雑な分岐を無理に1つの when() にまとめてしまうと逆に分かりづらくなる可能性があります。シンプルに書ける範囲で利用するのがおすすめです。

参考記事

https://x.com/MrPunyapal/status/1894396364395876498

Laravelダイジェスト

Discussion