Collection::pipeInto()
Pass an entire collection into a class constructor — transform collection pipelines into domain objects in a single call.
Overview
pipeInto() passes the entire collection into a given class's constructor and returns the new instance. It's the bridge between a collection pipeline and a domain object or DTO, keeping your fluent chain unbroken.
Usage
use Illuminate\Support\Collection;
class SalesReport
{
public readonly float $total;
public readonly float $average;
public readonly int $count;
public function __construct(Collection $orders)
{
$this->total = $orders->sum('amount');
$this->average = $orders->avg('amount');
$this->count = $orders->count();
}
}
$report = Order::query()
->where('status', 'completed')
->whereMonth('created_at', now()->month)
->get()
->pipeInto(SalesReport::class);
$report->total; // 45230.50
$report->average; // 1507.68
$report->count; // 30
Compared to pipe()
pipe() passes the collection to a closure; pipeInto() passes it to a class constructor:
// pipe() — closure-based
$result = $collection->pipe(fn ($items) => new Report($items));
// pipeInto() — class-based, cleaner
$result = $collection->pipeInto(Report::class);
Real-World Example
Building a paginated response DTO:
class SearchResults
{
public readonly array $items;
public readonly array $facets;
public function __construct(Collection $results)
{
$this->items = $results->pluck('item')->all();
$this->facets = $results
->pluck('category')
->countBy()
->sortDesc()
->all();
}
}
$results = Product::search($query)
->get()
->pipeInto(SearchResults::class);
When to Use
- Converting collection results into DTOs or value objects
- Encapsulating post-processing logic in a dedicated class
- Keeping controller code fluent — query, transform, and wrap in one chain
- Any time you'd write
new SomeClass($collection)at the end of a pipeline