Collection of PSR-15 middlewares
This is a migration of most psr7-middlewares to follow PSR-15 specification (currently released as 0.2.0
of php-interop/http-middleware
).
- PHP >= 5.6
- A PSR-7 http mesage implementation (Diactoros, Guzzle, Slim, etc...)
- A PSR-15 middleware dispatcher (Middleman, etc...)
Main differences with psr7-middlewares:
PSR-15
defines a set of interfaces for interoperability with PSR-7
middleware adding the following changes:
- The double-pass signature
function ($request, $response, $next)
is replaced by the new lambda-style:function ($request, $next)
. - There are two different interfaces:
MiddlewareInterface
andServerMiddlewareInterface
in order to differentiate between middlewares requiring aRequestInterface
or aServerRequestInterface
.
This is something requested by some people so with the PSR-15 comming up, this is a good opportunity to port these components in individual packages.
In the old psr7 version, some components insert automatically values in the request attributes in a way that is hard to recover. For example, in ClientIp to get the user ip you need to use a static function:
use PsrMiddlewares\Middleware\ClientIp;
$ip = ClientIp::getIp($request);
Because the "hard" way is:
$data = $request->getAttribute('Psr7Middlewares\\Middleware');
$ip = isset($data['CLIENT_IPS'][0]) ? $data['CLIENT_IPS'][0] : null;
This was done to avoid conflicts with other attributes, but for convenience I decided to remove this method and use configurable attribute names:
$ip = $request->getAttribute('client-ip'); //easy!!
Because the attribute name is configurable, you can use whatever you want in order to prevent conflict, for example, using a underscore as prefix:
$dispatcher[] = (new Middlewares\ClientIp)->attribute('_client-ip');
In the psr7 old version, some components uses "resolvers" to do different things deppending of some circunstances (content-type, encoding, etc). Payload is an example of this: it can parse json, urlencoded or csv in the same class. Now this components have been splitted into subcomponents, so now there's a JsonPayload
, UrlEncodedPayload
and CsvPayload
. Easier to maintain and extend.
The middlewares has been moved to this organization. This is not the oscarotero's middlewares, this is simply "middlewares" and the community is welcome to participate.
use Zend\Diactoros\ServerRequestFactory;
use mindplay\middleman\Dispatcher;
use Middlewares;
$dispatcher = new Dispatcher([
//Handle errors
(new Middlewares\ErrorHandler())
->catchExceptions(true),
//Log the request
new Middlewares\AccessLog($app->get('logger')),
//Calculate the response time
new Middlewares\ResponseTime(),
//Removes the trailing slash
new Middlewares\TrailingSlash(false),
//Insert the UUID
new Middlewares\Uuid(),
//Disable the search engine robots
new Middlewares\Robots(false),
//Compress the response to gzip
new Middlewares\GzipEncoder(),
//Minify the html
new Middlewares\HtmlMinifier(),
//Override the method using X-Http-Method-Override header
new Middlewares\MethodOverride(),
//Parse the json payload
new Middlewares\JsonPayload(),
//Parse the urlencoded payload
new Middlewares\UrlEncodedPayload(),
//Save the client ip in the '_ip' attribute
(new Middlewares\ClientIp())
->attribute('_ip'),
//Allow only some ips
(new Middlewares\Firewall(['127.0.0.*']))
->ipAttribute('_ip'),
//Add cache expiration headers
new Middlewares\Expires(),
//Negotiate the content-type
new Middlewares\ContentType(),
//Negotiate the language
new Middlewares\ContentLanguage(['gl', 'es', 'en']),
//Create and save a session in '_session' attribute
(new Middlewares\AuraSession())
->attribute('_session'),
//Add the php debugbar
new Middlewares\Debugbar(),
//Handle the routes with fast-route
new Middlewares\FastRoute($app->get('dispatcher')),
]);
$response = $dispatcher->dispatch(ServerRequestFactory::fromGlobals());
Use the package repository of each component to notify any issue or pull request related with it, and use this repository for generical questions, new middlewares discussions, etc.
If you want to contribute with new middlewares, you can take a look to these ideas and create an issue to expose the functionality. There's also a skeleton that you can use for quick start.
See CONTRIBUTING for contributing details.
The MIT License (MIT). Please see LICENSE for more information.