laravel-when-conditional-queries-tip.png
Шаблон кодуLaravel

Laravel when(): Conditional Queries Without Extra if Statements

Use when() for conditional filters, pass the condition value into the callback, add an else branch with the third argument, and avoid falsy-value traps.

when() keeps optional filters inside one query chain instead of breaking query construction with separate if statements.

Its value goes beyond replacing a simple if. The callback can receive the condition value, the third argument acts like else, and falsy values such as 0 need deliberate handling.

Basic when() Usage

До
php
$query = User::query(); if ($status) {    $query->where('status', $status);} $users = $query->get();
Після
php
$users = User::query()    ->when(        $status,        fn ($query, $status) =>            $query->where('status', $status),    )    ->get();

Laravel passes more than the builder into the callback. The callback can receive the value supplied as the first argument to when(), so a separate use ($status) is unnecessary.

PHP - The condition value is available in the callback
User::query()    ->when(        $status,        fn ($query, $status) =>            $query->where('status', $status),    );

The Third when() Argument Is the else Branch

The full form when($value, $callback, $default) accepts a second callback. It runs when the first argument is falsy, giving you an if / else shape without leaving the fluent chain.

PHP - when() with a default callback
User::query()    ->when(        $sortByVotes,        fn ($query) => $query->orderBy('votes'),        fn ($query) => $query->orderBy('name'),    )    ->get();

The Trap: 0 and Other Falsy Values

До
php
Product::query()    ->when(        $minPrice,        fn ($query, $minPrice) =>            $query->where('price', '>=', $minPrice),    );
Після
php
Product::query()    ->when(        $minPrice !== null,        fn ($query) =>            $query->where('price', '>=', $minPrice),    );
when() checks the truthiness of its first argument. If 0 is a valid filter value, pass an explicit boolean condition such as $minPrice !== null.

when() Is Not Limited to where()

PHP - Several independent optional filters in one chain
Product::query()    ->when(        $categoryId,        fn ($query, $categoryId) =>            $query->where('category_id', $categoryId),    )    ->when(        $onlyAvailable,        fn ($query) =>            $query->where('stock', '>', 0),    )    ->when(        $sortByPrice,        fn ($query) =>            $query->orderBy('price'),    )

when() is useful whenever a condition modifies the same builder: it can conditionally add where(), orderBy(), joins, selects, and other query clauses.

You do not need to replace every if with when(). If a separate condition is clearer outside the chain, a normal if is still the better shape. Laravel also provides unless() for the inverse condition.

#when #query-builder #eloquent #conditional-queries #laravel-12 #laravel-13 #php-8-4 #php-8-5

Схожі поради

laravel-withwherehas-avoid-duplicate-conditions-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #where-has #with-where-has #eager-loading #relationships
laravel-tap-side-effects-keep-original-value-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #tap #helpers #tappable
laravel-firstorcreate-replace-first-create-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #model-persistence #first-or-create #first-or-new
laravel-updateorcreate-replace-first-if-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #update-or-create #model-persistence #upsert