PHPackages                             teewurst/pipeline - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. teewurst/pipeline

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

teewurst/pipeline
=================

Recursive Pipeline Construct

3.0.1(3y ago)38.3k↓87.5%1[1 PRs](https://github.com/teewurst/pipeline/pulls)1MITPHPPHP ^7.4|^8.0CI failing

Since Jan 14Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/teewurst/pipeline)[ Packagist](https://packagist.org/packages/teewurst/pipeline)[ RSS](/packages/teewurst-pipeline/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (7)Versions (9)Used By (1)

Simple Recursive Pipeline with few dependencies
===============================================

[](#simple-recursive-pipeline-with-few-dependencies)

With this lib, we are able to separate long executions into multiple tasks. A pipeline enables you to better fulfill single responsibility requirements. This results in better maintainability and testability.

### How to

[](#how-to)

- The Pipeline passes the Payload and its self into the task.

`public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface;`

- The first task calls the next task, calls the next task, calls the next task ...

`$payloadAfterAllSteps = $pipeline->handle($payload);`

- Like in PSR-7 (the request object) you are now able to handle all information by adding and getting information from a payload object

```
$value = $genericPayload->getValue();
$value++;
$genericPayload->setValue($value);

```

##### Step-by-Step

[](#step-by-step)

1. Create Task(s)
2. Initialize Pipeline
3. Fill Payload
4. Execute Pipe
5. Evaluate Pipe

### Use Pipeline Service

[](#use-pipeline-service)

You are able to simple create your pipelines from your DI (PSR-11 Container Service Manager required). It just takes two lines of code (+Config)

The `PipelineService` class allows you to pass tasks as service hashes.

```
// .. In your factory
$tasksFromEnvConfig = $config->getTasks() // somewhere in your config: [Task1::class, Task2::class, Task3::class];
$pipeline = (new PipelineService)->createPsr11($serviceManager, $tasksFromEnvConfig);
```

With teewurst/Pipeline you are able to create quite complex tasks in no time:

```
// Configuration of BiPRO Request (= German XML Request Standard)
$tasklist = [
    CheckServiceAvailabilityTask::class,
    [ // do Request
        ErrorHandlerTask::class, // catch execution of submission even on error
        [
            PrepareDataTask::class,
            ValidateDataTask::class,
            DoGetOfferRequestTask::class
        ],
        // .. some additional things like set quote, upload documents etc.
    ],
    [ // do something additionally
        LogResultLocalyTask::class,
        LogResultInDWTask::class,
    ]
];
```

### Best Practices

[](#best-practices)

- Use `RecursivePipeline` to create "Sub Pipelines" =&gt; Dynamic Tasks
- Because of the Structure every task has a "before handle next step" and "after handle next step"
- Interrupt pipeline by throwing an exception or return $payload without handling the next step

### Examples

[](#examples)

##### Initialize Pipeline manually

[](#initialize-pipeline-manually)

Of course it would be better to use DI instead of `new` all the time

```
// Create Tasks in order of execution
$tasks = [
    new ExceptionTask(),
    new ErrorBagTask(),
    new OpenStreamTask(),
    new ReadValuesTask(),
    new ValidateValuesTask(),
    new RequireDocumentsTask(),
    new HandleImportTask(),
];

// Create Pipeline
$pipeline = new \teewurst\Pipeline\Pipeline($tasks);

// Create Payload
$payload = new ImportPayload();

// Setup Payload
$payload->setEnvironment($env); // setOptions(...)
$payload->setConfig($config);

// Do the thing the pipeline is constructed for
$payload = $pipeline->handle($payload);
// Evaluate result
$payload->getMessage();
```

##### Simple Task which does something

[](#simple-task-which-does-something)

Use the pipeline object to pass configuration and handle data between tasks

```
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface {
    // there is something, so we need to continue with our tasks
    if ($payload->getValue() > 0) {
        return $pipeline->handle($payload);
    }

    // we do not allow negative values => Completely interrupt process
    if ($payload->getValue() < 0) {
        throw new \Exception("Negative Values are not allowed here");
    }

    // Value is 0, let's pretend there is nothing more to do. => Interrupt from here and go back up the callstack
    return $payload;
}
```

##### Exception Handling Task

[](#exception-handling-task)

Handle (maybe only certain) exceptions within the pipe

```
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface {
    try {
        // handle next steps BEFORE doing something
        $payload = $pipeline->handle($payload);
    } catch (\Throwable $e) {
        $this->logger->logException($e, ['context' => $payload]);
    }
    return $payload;
}
```

##### Error Bag

[](#error-bag)

Process multiple errors with error bags

```
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface {
    // Do something before handle next steps
    $payload->setErrorBag($this->errorBag);

    // Pipeline will add errors to error bag
    $payload = $pipeline->handle($payload);

    // "On the way back" and after handling, we check if something is inside the error bag
    if ($payload->getErrorBag()->hasErrors()) {
        $payload->setMessage($payload->getErrorBag()->toString());
    }

    return $payload;
}
```

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance53

Moderate activity, may be stable

Popularity23

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~171 days

Recently: every ~74 days

Total

6

Last Release

1456d ago

Major Versions

v1.0 → v2.0.02021-07-30

v2.0.2 → 3.0.02022-01-08

PHP version history (2 changes)v1.0PHP ^7.4

v2.0.0PHP ^7.4|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/a282e21cfabda806f3df3d5a7981256db6a6ce6b015805dc080b21aa2fd0ac0b?d=identicon)[teewurst](/maintainers/teewurst)

---

Top Contributors

[![teewurst](https://avatars.githubusercontent.com/u/7197260?v=4)](https://github.com/teewurst "teewurst (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/teewurst-pipeline/health.svg)

```
[![Health](https://phpackages.com/badges/teewurst-pipeline/health.svg)](https://phpackages.com/packages/teewurst-pipeline)
```

###  Alternatives

[symfony/dependency-injection

Allows you to standardize and centralize the way objects are constructed in your application

4.2k431.1M7.5k](/packages/symfony-dependency-injection)[illuminate/contracts

The Illuminate Contracts package.

705122.9M10.1k](/packages/illuminate-contracts)[illuminate/container

The Illuminate Container package.

31178.1M2.0k](/packages/illuminate-container)[ecotone/ecotone

Supporting you in building DDD, CQRS, Event Sourcing applications with ease.

558549.8k17](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[internal/dload

Downloads binaries.

98142.7k10](/packages/internal-dload)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
