Windwalker Middleware is a simple & elegant PHP Middleware library help you integrating middleware pattern in your project.
Add this to the require block in your composer.json
.
{
"require": {
"windwalker/middleware": "~3.0"
}
}
This is a simple way using middleware to wrap your logic.
use Windwalker\Middleware\CallbackMiddleware;
use Windwalker\Middleware\AbstractMiddleware;
class TestA extends AbstractMiddleware
{
/**
* call
*
* @return mixed
*/
public function call()
{
echo ">>> AAAA\n";
$this->next->call();
echo "<<< AAAA\n";
}
}
class TestB extends AbstractMiddleware
{
/**
* call
*
* @return mixed
*/
public function call()
{
echo ">>> BBBB\n";
$this->next->call();
echo "<<< BBBB\n";
}
}
$a = new TestA;
$a->setNext(new TestB);
$a->call();
The result should be:
>>> AAAA
>>> BBBB
<<< BBBB
<<< AAAA
If you don't want to create a class, you want to set a middleware in runtime, using CallbackMiddleware
$a = new TestA;
$b = new TestB;
$a->setNext($b);
$b->setNext(new CallbackMiddleware(
function($next)
{
echo ">>>CCCC\n";
echo "<<<CCCC\n";
}
));
$a->call();
The result should be:
>>> AAAA
>>> BBBB
>>> CCCC
<<< CCCC
<<< BBBB
<<< AAAA
The CallbackMiddleware
support second argument as next in constructor:
$ware = new CallbackMiddleware(
function($next)
{
echo ">>>CCCC\n";
$next->call();
echo "<<<CCCC\n";
},
new NextMiddleware
)
If a middleware call next, we have to make sure there are a next middleware exists, or we will return error.
class TestB extends Middleware
{
/**
* call
*
* @return mixed
*/
public function call()
{
echo ">>> BBBB\n";
$this->next->call();
echo "<<< BBBB\n";
}
}
$b = new TestB;
$b->call();
// Error, next not exists.
But yes we can set a blackhole middleware in the last element, that will do nothing when previous class call it, using EndMiddleware
:
$b = new TestB;
$b->setNext(new EndMiddleware);
$b->call();
The result still like below:
>>> BBBB
<<< BBBB
We can using ChainBuilder
to chaining multiple middlewares.
use Windwalker\Middleware\Chain\ChainBuilder;
$chain = new ChainBuilder;
$chain
->add('TestA')
->add(new TestB)
->add(function($next)
{
echo ">>>CCCC\n";
echo "<<<CCCC\n";
});
$chain->call();
The result still:
>>> AAAA
>>> BBBB
>>> CCCC
<<< CCCC
<<< BBBB
<<< AAAA
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Windwalker\Middleware\Chain\Psr7ChainBuilder;
use Windwalker\Middleware\Psr7Middleware;
class MyPsr7Middleware implements \Windwalker\Middleware\Psr7InvokableInterface
{
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next = null)
{
// Do something
$result = $next($request, $response);
// Do something
return $result;
}
}
$mid = new Psr7Middleware(function (ServerRequestInterface $request, ResponseInterface $response, $next = null)
{
// Do something
});
$chain = new Psr7ChainBuilder;
$chain->add(new MyPsr7Middleware)
->add($mid);
$chain->execute(new ServerRequest, new Response);