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.
composer require sanmai/pipelineuse Sanmai\Pipeline\Pipeline;$result = (new Pipeline())
->pipe(fn ($order) => $order->validate())
->pipe(fn ($order) => $order->applyDiscounts())
->pipe(fn ($order) => $order->formatForOutput())
->run($initialOrder);
@var or generic types (e.g., Pipeline<Order, FormattedOrder>) for IDE and static analysis support.ValidateOrderStage::class) and inject into pipelines or pipeline builders.pipeIf(): Insert conditional logic:
$pipeline->pipeIf($isPremium, fn ($user) => $user->upgrade());
App\Actions, job middleware, or as part of form request handling (format() and authorize() chains). Wrap logic around $request->all() or custom DTOs.pipe() boundary or at the end. Use debug() to peek into intermediate states.compose():
$validation = (new Pipeline())->pipe(...)->pipe(...);
$processing = (new Pipeline())->pipe(...)->pipe(...);
$full = $validation->compose($processing);
debug() to inspect the payload mid-pipeline without breaking flow:
$pipeline->pipe(fn ($x) => $x + 1)
->debug('After increment') // logs or yields payload
->pipe(fn ($x) => $x * 2);
try/catch or use pipe(fn () => throw ...) — but prefer graceful return of error objects (e.g., Result DTO) to keep pipeline state explicit.Stage classes implementing __invoke() to share complex logic (e.g., rate limiting, transaction wrapping).pipe() adds negligible overhead — avoid dynamic stage injection inside loops; build and reuse pipelines instead.How can I help you explore Laravel packages today?