Skip to main content

What is the Conditionable trait?

Illuminate\Support\Traits\Conditionable adds when() and unless() to any class that uses it. These methods let you branch logic conditionally while keeping a fluent method chain intact.
The source lives in src/Illuminate/Conditionable/Traits/Conditionable.php. The Illuminate\Support\Traits\Conditionable namespace is an alias that points there.
Many Laravel classes use this trait: QueryBuilder, Eloquent Builder, Mail, Notification, and others.

Basic usage

when() — execute when the condition is truthy

When the first argument is truthy the second argument (callback) runs. When it is falsy the optional third argument (default callback) runs instead.

unless() — execute when the condition is falsy

unless() is the inverse of when(). The callback runs when the condition is falsy.

Why the chain continues

When the callback returns null, when() returns $this so the chain continues. When the callback returns a value, that value becomes the next item in the chain.
The source implementation is:
When the callback returns an explicit value, that value flows to the next call in the chain. When the callback returns nothing (null), $this is returned instead.

Calling when() with no arguments — HigherOrderWhenProxy

Calling when() with zero arguments returns a HigherOrderWhenProxy. This lets you set the condition lazily.
Calling when() with one argument returns a proxy that holds that value as the condition.

Passing a closure as the condition

When the first argument is a closure, the closure’s return value is used as the condition.
This lets you encapsulate the condition evaluation inside a callback.

The classic QueryBuilder pattern

Dynamic query building with when() is the most common use case.

Adding Conditionable to your own classes

Use the trait in any class to get when() and unless() for free.

Using when() with Mail and Notifications

when() is available in Mailable and Notification classes too.

when() vs tap()

Both look similar but serve different purposes.
If you only want to trigger a side effect (logging, debugging) mid-chain, use tap(). Use when() or unless() when you need to change behavior based on a condition.

Next steps

Higher order messages

Learn how the $collection->map->method() syntax works and how to use it in practice.
Last modified on March 28, 2026