PHPackages                             andydune/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. andydune/pipeline

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

andydune/pipeline
=================

Provides a pipeline pattern. Based on middleware approach.

v2.0.0(7y ago)63.6k1MITPHPPHP &gt;=7.1CI failing

Since Sep 21Pushed 6y ago1 watchersCompare

[ Source](https://github.com/AndyDune/Pipeline)[ Packagist](https://packagist.org/packages/andydune/pipeline)[ Docs](https://github.com/AndyDune/Pipeline)[ RSS](/packages/andydune-pipeline/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (2)Versions (19)Used By (1)

AndyDune\\Pipeline
==================

[](#andydunepipeline)

[![Build Status](https://camo.githubusercontent.com/0502aa98a8120bdc42463abbcbacefe638c3fc9ec56360ed477c9e61f3930aef/68747470733a2f2f7472617669732d63692e6f72672f416e647944756e652f506970656c696e652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/AndyDune/Pipeline)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Packagist Version](https://camo.githubusercontent.com/9f0b89ace40ff570f2118b0b07ac010b8e1792b6b5d5ee808d8da3b0701c498e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616e647964756e652f706970656c696e652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/andydune/pipeline)[![Total Downloads](https://camo.githubusercontent.com/b2a5af8b1233e74c63f43b2a1833660e0855d1f6ec52baa9a9034a1ef3a35c2e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616e647964756e652f706970656c696e652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/andydune/pipeline)

This package provides a pipeline pattern implementation. It is based on middleware approach.

Requirements
------------

[](#requirements)

PHP version &gt;= 7.1

For php 5.6 use version 1:

```
"require" : {
     "andydune/pipeline": "1.*"
}

```

Installation
------------

[](#installation)

Installation using composer:

```
composer require andydune/pipeline

```

Or if composer was not installed globally:

```
php composer.phar require andydune/pipeline

```

Or edit your `composer.json`:

```
"require" : {
     "andydune/pipeline": "^2"
}

```

And execute command:

```
php composer.phar update

```

Usage
-----

[](#usage)

Operations in pipeline stages, can be anything that satisfies the `callable`type-hint. So closures and anything that's invokable is good.

```
use AndyDune\Pipeline\Pipeline;

$pipeline = new Pipeline();

$stages = [
    function($contest, $next) {
        $contest += 100;
        return $next($contest);
    },
    function($contest, $next) {
        $contest += 10;
        return $next($contest);
    }
];
$result = $pipeline->through($stages)->send(1)
->then(function ($context) {
            $context += 1000;
            return $context;});
$result // 1111
```

Types of stages
---------------

[](#types-of-stages)

Basically each stage can be `Closure`:

```
$pipeline = new Pipeline();
$pipeline->pipe(function ($context, $next) {
    $context['closure'] = 'was here';
    return $next($context);
});
```

It can be an instance of class with callable interface:

```
$instance = new class() {
    public function __invoke($context, $next)
    {
        $context['invoke'] = 'was here';
        return $next($context);
    }
}

$pipeline = new Pipeline();
$pipeline->pipe($instance);
```

It can be an instance of class with any method:

```
$instance = new class() {
    public function doIt($context, $next)
    {
        $context['invoke'] = 'was here';
        return $next($context);
    }
}

$pipeline = new Pipeline();
$pipeline->pipe($instance, 'doIt');
```

It can be a class name with method `__invoke` or any method you describe:

```
class Trim
{
    public function __invoke($context, $next)
    {
        $context['class_invoke'] = 'was here';
        return $next($context);
    }
}

$pipeline = new Pipeline();
$pipeline->pipe(Trim::class);
```

It can be a class name with any method you describe:

```
class Trim
{
    public function handle($context, $next)
    {
        $context['class_invoke'] = 'was here';
        return $next($context);
    }
}

$pipeline = new Pipeline();
$pipeline->pipe(Trim::class,  'handle');
```

Use object for stage without middleware interface
-------------------------------------------------

[](#use-object-for-stage-without-middleware-interface)

You can use methods which don't execute $next function. It gets some data and return results. There is special method: 'pipeForContainer'

Example class.

```
namespace AndyDune\Pipeline\Example;

class Methods
{
    // return result - no calling next()
    public function addBraceLeft($string)
    {
        return '(' . $string;
    }

    // It has middleware interface
    public function addBraceRight($string, callable $next)
    {
        $string =  $string . ')';
        return $next($string);
    }
}
```

```
$instance = new Methods();

$pipeline = new Pipeline();
$pipeline->send('puh');

$pipeline->pipeForContainer($instance, 'addBraceLeft');

$pipeline->pipe(Methods::class, 'addBraceRight');
$result = $pipeline->execute();

$result == '(puh)';
```

Container provider (service provider)
-------------------------------------

[](#container-provider-service-provider)

String can de passed as pipeline stage. By default it is a class name. It's make possible by using default provider: `AndyDune\Pipeline\PipeIsClassName`
You can set your own provider, with injections you need. Your class must implements interface: `Interop\Container\ContainerInterface`

If was not found stage with your provider system will try to use default provider. There is stack of providers.

Use your provider as parameter for pipeline constructor:

```
use Interop\Container\ContainerInterface;

class SpecialPipelineContainer implements ContainerInterface
{
    /**
     * @var  \Rzn\ObjectBuilder
     */
    protected $objectBuilder;

    public function get($name)
    {
        /*
        do anything to build object using $name
        */
        return $object;
    }

    public function has($name)
    {
        /*
        do anything to check required object can be build
        */
        return $exist;
    }
}

$container = new SpecialPipelineContainer();
$pipeLine = new Pipeline($container);

$pipeLine->pipe('any string to get stage from container');
```

Additional parameters for stage
-------------------------------

[](#additional-parameters-for-stage)

Sometimes you need to pass any number of additional parameters to pipe stage during description. It needs for test and it very good for more flexibility of stage. It increases reuse of class.

Lets look at the example. It is very simple example.

Here is example class for stage:

```
namespace AndyDune\Pipeline\Example;
class PowerOfNumber
{
    public function __invoke($data, callable $next, $power = 2)
    {
        if (is_array($power)) {
            array_walk($power, function (&$value, $key) use ($data) {
                $value = pow($data, $value);
            });
            return $next($power);
        }
        $data = $this->handle($data, $power);
        return $next($data);
    }
    protected function handle($number, $power)
    {
        return pow($number, $power);
    }
}
```

Lets use it:

```
    use use AndyDune\Pipeline\Pipeline;
    use AndyDune\Pipeline\Example;

    $pipeline = new Pipeline();
    $pipeline->send(2);
    $pipeline->pipe(PowerOfNumber::class);
    $result = $pipeline->execute(); // == 4

    $pipeline = new Pipeline();
    $pipeline->send(2);
    $pipeline->pipe(PowerOfNumber::class, null, 3);
    $result = $pipeline->execute(); // == 8

    $pipeline = new Pipeline();
    $pipeline->send(2);
    $pipeline->pipe(PowerOfNumber::class, null, 4);
    $result = $pipeline->execute(); // == 16
```

Dependency injection
--------------------

[](#dependency-injection)

You can use default pipeline stage creator with injection into stage objects services or any objects from outside.

There is injection with interfaces.

```
    use use AndyDune\Pipeline\Pipeline;

    $pipeline = new Pipeline();

    $pipeline->addInitializer(function($stageObject) use ($someService) {
        if ($stageObject instanceof SomeServiceAwareInterface) {
            $stageObject->setSomeService($someService)
        }
    });

    $pipeline->pipe(ClassHaveInterface::class);
    $result = $pipeline->execute();
```

This use method `addInitializer` which receive callable parameter.

Exceptions
----------

[](#exceptions)

Package has not integrated exception catch support. It is simple for you to include exception *try-catch* block into one of pipeline stages.

```
    use AndyDune\Pipeline\Pipeline;
    $pipeline = new Pipeline();
    $pipeline->send(['zub' => 'kovoy']);
    $pipeline->pipe(function ($context, $next) {
        try {
            return $next($context);
        } catch (Exception $e) {
            $context['exception'] = 'caught';
        }
        return $context;
    });

    $pipeline->pipe(function ($context, $next) {
        $context['action'] = 'before_exception';
        throw new Exception();
        return $next($context); // it will be never execute
    });

    // This stage will never be executed
    $pipeline->pipe(function ($context, $next) {
        $context['after_exception'] = 'ignored';
        return $next($context);
    });

    $result = $pipeline->execute();
    array_key_exists('zub', $result);       // true
    array_key_exists('exception', $result); // true
    array_key_exists('action', $result);    // false
    array_key_exists('after_exception', $result); // false
```

There is a class you may use as stage for your pipeline for catch exception in this package.

```

    $pipeline = new Pipeline();
    $pipeline->send(['zub' => 'kovoy']);
    $pipeline->pipe(AndyDune\Pipeline\Stage\ExceptionCatch::class);
    $pipeline->pipe(function ($context, $next) {
        $context['action'] = 'before_exception';
        throw new Exception('jump');
    });
    $result = $pipeline->execute();

    $result instancheof \Exception // true
```

Examples
--------

[](#examples)

### Caching

[](#caching)

You have service for retrieve data. And you don't need to change its code. Just use it as a stage in the pipeline.

```
// Description
$pipeline = new Pipeline();
$pipeline->pipe(function($key, $next) {
    /*
    * Cache adapter with (PSR-16) interface
    * Ones a have used Symfony Cache Component [https://github.com/symfony/cache]
    * It's for example
    */
    $cache = new FilesystemCache();
    if ($cache->has($key)) {
        return $cache->get($key);
    }
    $data = $next($catId);
    $cache->set($key, $data);
    return $data;
});
$pipeline->pipe(DataRetrieveClass::class, 'getImportantData');

// Execute
$results = $pipeline->send($key)->execute();
```

Usage within Zend FW 3
----------------------

[](#usage-within-zend-fw-3)

By default string as stage for pipeline means name of class. If you create pipeline object without parameters service container implements `AndyDune\Pipeline\PipeIsClassName`. It only creates instance of given class and return it. If this package is used as part of of *Zend FW 3* you can use Zend's services for retrieve instances.

First you must install package with composer. Then copy file `vendor/andydune/pipeline/config/pipeline.global.php` to `config/autoload/pipeline.global.php`

Description fot your pipeline in factory:

```
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
class DunhillFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $pipeline = $container->get('pipeline');
        $pipeline->pipe('service name within Zend3');
        $pipeline->pipe(function($data, $next) {
            return $next($data);
        });
        return $pipeline;
    }
}
```

If you don't work with Zend services use pipeline directly.

Analogues
---------

[](#analogues)

[Laravel pipeline](https://laravel.com/api/5.5/Illuminate/Pipeline.html) - it do very the same I wanted, but I need more tools for testing purpose. And I don't like laraver service manager. it has not common interface. My pipeline may use service managers based on [container-interop with PSR-11 interfaces](https://github.com/container-interop/container-interop).

[League\\Pipeline](https://github.com/thephpleague/pipeline) - it has good documentation. But has bad feature - poor workflow control. To stop execution it need to use exception.

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community9

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 ~38 days

Recently: every ~124 days

Total

16

Last Release

2628d ago

Major Versions

v0.8.1 → v1.0.02017-10-05

v1.5.0 → v2.0.02019-04-23

PHP version history (3 changes)v0.5PHP ^5.6 || ^7.0

v1.3.0PHP ^5.6 || ^7

v2.0.0PHP &gt;=7.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/79da3b2173a2cefb36abc9b4707cf2c633df8f2c748633ccf64186f5c0e7be6c?d=identicon)[AndyDune](/maintainers/AndyDune)

---

Top Contributors

[![AndyDune](https://avatars.githubusercontent.com/u/3772910?v=4)](https://github.com/AndyDune "AndyDune (72 commits)")

---

Tags

middlewarephppipelineworkflowphpmiddlewarepipeline

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[imanghafoori/laravel-middlewarize

Use laravel middlewares on any method calls in your app

1124.5k1](/packages/imanghafoori-laravel-middlewarize)[aldemeery/onion

A layering mechanism for PHP applications.

5813.4k4](/packages/aldemeery-onion)

PHPackages © 2026

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