Der Trait Illuminate\Support\Traits\Conditionable erweitert ein Objekt um die Methoden when() und unless(). Sein Kennzeichen: Sie können Verzweigungen einbauen und dennoch die Method-Chain fortsetzen.
Der eigentliche Quellcode befindet sich unter src/Illuminate/Conditionable/Traits/Conditionable.php und wird über den Alias Illuminate\Support\Traits\Conditionable referenziert.
Viele Klassen von Laravel wie QueryBuilder, EloquentBuilder, Mail oder Notification setzen diesen Trait ein.
Ist der Wert des ersten Arguments wahr, wird der Callback des zweiten Arguments ausgeführt. Ist er falsch, wird der Standard-Callback des dritten Arguments ausgeführt.
Gibt der Callback null zurück, wird $this (das Objekt, das den Trait verwendet) zurückgegeben. Gibt der Callback etwas anderes als null zurück, wird dieser Rückgabewert weitergereicht.
// Da $this zurückgegeben wird, kann die Chain weiterlaufen$query = User::query() ->when($request->has('active'), function ($query) { $query->where('active', true); // gibt void / null zurück }) ->when($request->filled('name'), function ($query) use ($request) { $query->where('name', 'like', "%{$request->name}%"); }) ->orderBy('created_at', 'desc');
Ruft man when() ganz ohne Argumente auf, wird ein HigherOrderWhenProxy zurückgegeben. Damit können Sie die Bedingung nachträglich festlegen.
$query = User::query() ->when()->isActive() // isActive() wird als Bedingung ausgewertet ->where('role', 'admin');
Mit einem einzigen Argument erhalten Sie einen Proxy, der diesen Wert als Bedingung speichert.
// Ein Argument: nur die Bedingung übergeben, Proxy erhalten$proxy = collect([1, 2, 3])->when($request->has('filter'));// Über $proxy->methodName() lässt sich methodName() nur bei wahrer Bedingung aufrufen
tap() und when() ähneln sich, verfolgen aber unterschiedliche Ziele.
tap()
when()
Zweck
Seiteneffekte (Logging, Debugging)
Verzweigung
Rückgabewert
immer $this
bedingt $this oder der Rückgabewert des Callbacks
Bedingung
nein
ja
// tap: für Seiteneffekte. Der Rückgabewert ist immer $this$user = User::find($id) ->tap(fn ($user) => Log::info("User {$user->id} loaded"));// when: für Verzweigung$user = User::query() ->when($isAdmin, fn ($q) => $q->where('role', 'admin')) ->first();
Wollen Sie nur Debugging oder Seiteneffekte innerhalb der Chain unterbringen, nutzen Sie tap(). Wollen Sie den Ablauf abhängig von einer Bedingung umschalten, verwenden Sie when() / unless().