sanmai/pipeline
sanmai/pipeline is a lightweight PHP pipeline library to process data through a chain of stages. Compose reusable, testable transformations with clear input/output flow, and plug in custom middleware-like steps for flexible processing in any app.
To make the most of the Pipeline library, follow these best practices for writing clean, efficient, and maintainable code.
The library is designed for streaming data. Always prefer iterators and generators over arrays for large datasets to minimize memory usage.
// Good: Streaming from a file
$result = take(new SplFileObject('data.csv'))
->map('str_getcsv')
->toList();
// Good: Forcing a stream from a large array
$result = take($largeArray)
->stream()
->filter(fn($user) => $user['active'])
->toList();
When working with arrays, be aware that certain methods (filter(), cast(), slice(), chunk()) use PHP's native array functions for performance. This means they create intermediate arrays:
// This creates intermediate arrays in memory:
$result = take($millionRecords)
->filter(fn($r) => $r['active']) // New array with ~500k elements
->map(fn($r) => transform($r)) // Another array with ~500k elements
->toList();
// Better: Use stream() for large arrays
$result = take($millionRecords)
->stream() // Process one element at a time
->filter(fn($r) => $r['active'])
->map(fn($r) => transform($r))
->toList();
Keep your operations in a single, fluent chain for readability and efficiency.
// Good: A single, readable chain
$result = take($data)
->filter($predicate)
->map($transformer)
->toList();
// Bad: Breaking the chain creates unnecessary intermediate variables
$filtered = take($data)->filter($predicate)->toList();
$result = take($filtered)->map($transformer)->toList();
fold() for AggregationsFor clarity and type safety, use fold() instead of reduce() for all aggregation tasks. It requires an explicit initial value, which makes your code more predictable.
// Good: Explicit initial value
$sum = take($numbers)->fold(0, fn($a, $b) => $a + $b);
// Bad: Implicit initial value
$sum = take($numbers)->reduce();
When cleaning data, use filter(strict: true) to only remove null and false values. This prevents accidental removal of falsy values like 0 or empty strings.
// Good: Predictable cleaning
$cleaned = take($data)->filter(strict: true);
// Bad: Aggressive cleaning may remove valid data
$cleaned = take($data)->filter();
Write defensive code to handle potential errors gracefully.
// Handle missing keys with the null coalescing operator
$result = take($users)
->map(fn($user) => [
'id' => $user['id'] ?? null,
'name' => $user['name'] ?? 'Unknown',
])
->filter(fn($user) => $user['id'] !== null)
->toList();
For complex pipelines, consider creating reusable functions or classes to encapsulate logic.
// Reusable pipeline function
function getActiveUsers(iterable $users): Standard
{
return take($users)
->filter(fn($user) => $user['active']);
}
$activeAdmins = getActiveUsers($allUsers)
->filter(fn($user) => $user['isAdmin'])
->toList();
array_sum, native PHP functions are often more efficient.How can I help you explore Laravel packages today?