tap()
tap() runs a callback on a value and then returns the value.
Syntax
tap($object, function ($object) { ... });The tap() helper passes a value to a callback so you can do something with it (log it, mutate it), then returns the original value regardless of what the callback returns. It keeps method chains fluent.
Example
Loading editor…
Press Run to execute the code.
When to use it
- A controller taps a newly created model to fire an analytics event before returning the model to the caller, without breaking the method chain.
- A query builder uses tap() to log the SQL generated by a complex scope while keeping the builder instance flowing through the chain.
- A service method taps a collection to write its contents to a debug log mid-pipeline without needing a temporary variable.
More examples
Tap to inspect and return unchanged
tap() passes the value to the closure as a side effect, then returns the original value — the log call's return value is discarded.
$user = tap(User::create($data), function ($user) {
Log::info('User created', ['id' => $user->id]);
});
// $user is the created model, NOT the return value of Log::info()Tap inside a method chain
Calls tap() on the Eloquent Builder to log the generated SQL query as a side effect without breaking or altering the query chain.
$orders = Order::query()
->where('status', 'pending')
->tap(fn($q) => Log::debug($q->toSql())) // log SQL mid-chain
->latest()
->get();Tap on a Collection mid-pipeline
Collection's tap() method fires a callback at any point in the fluent chain, here logging the count of paid invoices before summing amounts.
$totals = collect($invoices)
->filter(fn($inv) => $inv['paid'])
->tap(fn($c) => Log::info('Paid invoices: ' . $c->count()))
->sum('amount');
// Log fires after filter(), before sum()
Discussion