PSR-15 proposes a standard around PHP middleware that consumes PSR-7 HTTP message instances. One goal of the standard is to create interfaces that can co-exist with existing projects, which would allow adoption without necessarily leading to backwards compatibility breaks.
The most recent proposal has the following interfaces:
namespace Interop\Http\Middleware;
use PSR\Http\Message\RequestInterface;
use PSR\Http\Message\ResponseInterface;
use PSR\Http\Message\ServerRequestInterface;
interface DelegateInterface
{
public function process(RequestInterface $request) : ResponseInterface;
}
interface ServerMiddlewareInterface
{
public function process(ServerRequestInterface $request, DelegateInterface $delegate) : ResponseInterface;
}
interface MiddlewareInterface
{
public function process(RequestInterface $request, DelegateInterface $delegate) : ResponseInterface;
}DelegateInterface is roughly analogous to Zend\Stratigility\Next, while
ServerMiddlewareInterface is analogous to
Zend\Stratigility\MiddlewareInterface.
We'd take a tiered approach, over a minor version and a following major version.
First, we can update Next to implement DelegateInterface. At first, this
would be adding a process() method that proxies to __invoke(), and making
the ResponseInterface argument optional:
namespace Zend\Stratigility;
use Interop\Http\Middleware\DelegateInteface;
use PSR\Http\Message\RequestInterface;
use PSR\Http\Message\ResponseInterface;
use PSR\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
class Next implements DelegateInteface
{
public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response = null,
$err = null
) {
/* ... */
}
public function process(RequestInterface $request)
{
return $this($request);
}
}We'd also mark __invoke() as deprecated via annotation.
For the next major version, we'd modify __invoke() to proxy to process(). Since
one suggested change for v2
includes removal of the $err argument already, this version would also drop
the $response argument, so that it now reads:
namespace Zend\Stratigility;
use Interop\Http\Middleware\DelegateInteface;
use PSR\Http\Message\RequestInterface;
use PSR\Http\Message\ResponseInterface;
use PSR\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
class Next implements DelegateInteface
{
public function __invoke(ServerRequestInterface $request)
{
return $this->next($request);
}
public function next(RequestInterface $request)
{
/* ... */
}
}At the same time, we'd also mark the __invoke() method as deprecated; we might
potentially also raise an E_USER_DEPRECATED error within the __invoke()
method to encourage usage of the process() method.
For a minor version:
- We'd update
MiddlewarePipeto also allow PSR-15ServerMiddlewareInterfaceandMiddlewareInterfaceimplementations. - We'd update
Dispatchto check forServerMiddlewareInterfaceandMiddlewareInterfaceinstances; if found, it would invoke them with only the passed request. - We'd mark
MiddlewareInterfaceas deprecated. We'd add a class that can decorate callable middleware to be invoked as(See comment below for details on why this is now omitted.)ServerMiddlewareInterfaceimplementations. This would check the arity of the callable to ensure that it can be invoked per the PSR-15 specification.
For a major version:
- We'd remove
MiddlewareInterfaceentirely. Nextwould check if the handler is aServerMiddlewareInterfaceimplementation before dispatch (see the error handler proposal for details on why this goes inNextand notDispatch).- We'd update
MiddlewarePipeto only allowServerMiddlewareInterfaceandMiddlewareInterfaceimplementations.
PSR-15 is not yet accepted, and could still undergo revision, making it a moving target.
The one issue I'm running up against in current implementation of the next minor release is within
Next::__invoke(): lack of a$responseargument means:$responseargument to be null$doneargumentThis latter presents a problem, as it may require:
Nextwith a prototype response to use in these situations$responseprovided as the prototype