Skip to content

Instantly share code, notes, and snippets.

@jeffochoa
Last active April 23, 2024 21:22
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jeffochoa/347430a13042035db98c08c954cfcd7b to your computer and use it in GitHub Desktop.
Save jeffochoa/347430a13042035db98c08c954cfcd7b to your computer and use it in GitHub Desktop.
Understanding Laravel pipelines
<?php
namespace App\Features;
use App\Features\FirstTask;
use App\Features\SecondTask;
use Illuminate\Pipeline\Pipeline;
// *Naming things is hard* ... So, this is a class called `ProcessClass` that `run()` some text ¯\_(ツ)_/¯
class ProcessClass
{
protected $pipes;
public function __construct()
{
$this->pipes = $this->loadPipes();
}
public function loadPipes()
{
return [
FirstTask::class,
SecondTask::class
];
}
public function run($text)
{
return app(Pipeline::class)
->send($text)
->through($this->pipes)
->then(function ($text) {
return $text . "finally";
});
}
}
<?php
namespace App\Features;
use Closure;
class FirstTask
{
/**
* Changes the given text and return the result
**/
public function handle($text, Closure $next)
{
return $next($text . ' [first task] ');
}
}
<?php
namespace App\Features;
use Closure;
class SecondTask
{
/**
* Changes the given text and return the result
**/
public function handle($text, Closure $next)
{
return $next($text . ' [second task] ');
}
}
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Features\ProcessClass;
class PipelineTest extends TestCase
{
public function testExample()
{
$text = 'Initial test';
$object = new ProcessClass($text);
$result = $object->run($text);
$this->assertEquals('Initial test [first task] [second task] finally', $result);
}
}
PHPUnit 6.2.4 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 136 ms, Memory: 14.00MB

OK (3 tests, 3 assertions)
@judgej
Copy link

judgej commented Feb 21, 2020

Quick question: jumping out of a pipeline midway through - is that only possible by throwing an exception? For example, how does the Laravel middleware auth provider break the chain and issue a redirect if an auth task finds the user is not authenticated?

@michielgerritsen
Copy link

When you call $next($text); you basically call the next function. If you don't call it the chain is broken.

@judgej
Copy link

judgej commented Mar 26, 2020

Yes, I realised you can return anything other than the next closure, and the chain will break out immediately, returning that value you returned. Looking at the code, that seems to be the way it is designed to work, but does not seem to be explicitly mentioned in the documentation or any tutorials I have found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment