PSRs & Middleware Pipeline
This interfaces are already (and amazingly) implemented by Laminas at projects: Diactoros and Stratigility. Siler wraps them and exposes a function-friendly API handling state internally while achieving a fully-featured and declarative way for: Middleware Pipelining.
Siler doesn't have direct dependencies, to stay fit, it favors peer dependencies, which means you have to explicitly declare a
diactoros
dependency in your project in order to use it.composer require laminas/laminas-diactoros
You can create a superglobals seeded
ServerRequest
with Siler\Diactoros\request()
:use Siler\Diactoros;
$request = Diactoros\request();
And create Responses through helpers:
$json = Diactoros\json(['some' => 'data']);
$html = Diactoros\html('<p>some markup</p>');
$text = Diactoros\text('plain text');
If none of them fits your needs, you can create a raw Response:
$response = Diactoros\response();
$response->getBody()->write('something');
To emit a Response, there is no big deal, if you got Siler, you already imagined that is about one or two function calls, but this time we get the help from HttpHandlerRunner:
composer require laminas/laminas-httphandlerrunner
Then
HttpHandlerRunner\sapi_emit($response);
As in
Siler\Http\Response
namespace functions, the HttpHandlerRunner\sapi_emit
will output headers and text to the buffer, use it carefully.Example:
<?php declare(strict_types=1);
require_once 'vendor/autoload.php';
use Siler\Diactoros;
use Siler\HttpHandlerRunner;
use Siler\Route;
use function Siler\array_get;
$request = Diactoros\request();
$response = Route\match([
// /greet/Leo?salute=Hello
Route\get('/greet/{name}', function ($params) use ($request) {
$salute = array_get($request->getQueryParams(), 'salute', 'Olá');
return Diactoros\text("{$salute} {$params['name']}");
}, $request),
Route\get('/', function () {
return Diactoros\text('hello world');
}, $request),
Diactoros\text('not found', 404),
]);
HttpHandlerRunner\sapi_emit($response);
composer require laminas/laminas-stratigility
Siler doesn't have direct dependencies, to stay fit, it favors peer dependencies, which means you have to explicitly declare a
stratigility
dependency in your project in order to use it.A very simple Hello World example:
use function Siler\Diactoros\request;
use function Siler\Diactoros\text;
use function Siler\HttpHandlerRunner\sapi_emit;
use function Siler\Stratigility\handle;
use function Siler\Stratigility\pipe;
pipe(function ($request, $handler) {
return text('hello world');
});
sapi_emit(handle(request()));
It's more
use
s than actual code because Siler is abstracting all the way down for you.API | Description |
pipe | Creates a Stratigility MiddlewarePipe with a default name and pipes the given Clousure to it already wrapping it inside a MiddlewareInterface decorator, or you can pass any implementation MiddlewareInterface to it. |
text | Creates a Diactoros TextResponse . The Diactoros namespace in Siler is basically just helper functions for Responses. |
sapi_emit | Creates and immediately calls emit method on a HttpHandlerRunner SapiEmitter . |
handle | Calls handle on a MiddlewarePipe marshaling the Request. |
request | Creates a Diactoros ServerRequest using PHP's Globals. |
You can also run pipelines for specific routes:
use Siler\Diactoros;
use Siler\Http\Request;
use Siler\HttpHandlerRunner;
use Siler\Route;
use Siler\Stratigility;
$userMiddleware = function ($request, $handler) {
$token = Request\get('token');
if (empty($token)) {
return Diactoros\json('no user', 401);
}
$user = "get_user_by_token:$token";
$request = $request->withAttribute('user', $user);
return $handler->handle($request);
};
$homeHandler = function () {
return Diactoros\json('welcome');
};
$adminHandler = function ($request) {
return Diactoros\json(['user' => $request->getAttribute('user')]);
};
$secretHandler = function ($request) {
return Diactoros\json(['user' => $request->getAttribute('user')]);
};
Stratigility\pipe($userMiddleware, 'auth');
$request = Diactoros\request();
$response = Route\match([
Route\get('/', $homeHandler, $request),
Route\get('/admin', Stratigility\process($request, 'auth')($adminHandler), $request),
Route\get('/secret', Stratigility\process($request, 'auth')($secretHandler), $request),
Diactoros\json('not found', 404),
]);
HttpHandlerRunner\sapi_emit($response);
The second argument on
pipe
here is a Pipeline name, you can pipe middlewares to any number of pipelines, then in Stratigility\process
we marshal it, from the given $request
and returns a Closure to be called on a final handler.Last modified 3yr ago