GET /2015/06/using-psr-7-in-symfony/?user=kevin HTTP/1.1
Host: dunglas.fr
Accept: text/html
User-Agent: Kevin using Telnet
HTTP/1.1 301 Moved Permanently
Date: Tue, 07 Jul 2015 21:34:25 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=dbe0ddf9f8fa7b7379b4a3b0e2fe9b3871436304865; expires=Wed, 06-Jul-16 21:34:25 GMT; path=/; domain=.dunglas.fr; HttpOnly
Location: https://dunglas.fr/2015/06/using-psr-7-in-symfony/
Server: cloudflare-nginx
CF-RAY: 2026ac574100014c-CDG
0
Marshalling is repetitive and relatively hard to do.
if (isset($_GET['user']) && 'kevin' === $_GET['user']) {
syslog(LOG_INFO, 'Kevin was here');
}
header('Location: https://dunglas.fr/2015/06/using-psr-7-in-symfony/');
echo 0;
A first abstraction layer
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
$response = new Response('Hello');
$response->headers->setCookie(new Cookie(
'user',
$request->get('user', 'anonymous')
);
Introduced in Symfony 2.0. Used by Laravel, Drupal, phpBB, eZ Publish...
7M downloads for the standalone component. + almost 7M for the full stack framework.
These implementations are not interoperable.
Publish PHP Standard Recommendations (PSR).
MessageInterface
RequestInterface
ServerRequestInterface
ResponseInterface
UploadedFileInterface
StreamInterface
UriInterface
/** @var $request \Psr\Http\Message\ServerRequestInterface */
$queryParams = $request->getQueryParams();
if (isset($queryParams['user']) {
echo htmlspecialchars($queryParams['user']);
}
/** @var $response \Psr\Http\Message\ResponseInterface */
$response->withHeader('X-Foo', 'bar');
with*()
methods)Install:
composer require symfony/psr-http-message-bridge zendframework/zend-diactoros
namespace AppBundle\Controller;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Zend\Diactoros\Response;
class DefaultController extends Controller
{
public function indexAction(ServerRequestInterface $request)
{
$parsedBody = $request->getParsedBody(); // $_POST content
if (isset($parsedBody['message']) {
// Yeah, it's PSR-3 here
$this->get('logger')->info($parsedBody['message']);
}
$response = new Response();
$response->getBody()->write('Hello world');
$response = $response->withHeader('X-Best', 'Les-Tilleuls.coop');
return $response;
}
}
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Request;
$symfonyRequest = new Request(/* ... */);
// The HTTP_HOST server key must be set to avoid an unexpected error
$psr7Factory = new DiactorosFactory();
$psrRequest = $psr7Factory->createRequest($symfonyRequest);
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Response;
$symfonyResponse = new Response(/* ... */);
$psr7Factory = new DiactorosFactory();
$psrResponse = $psr7Factory->createResponse($symfonyResponse);
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
/** @var $psrRequest \Psr\Http\Message\ServerRequestInterface */
$httpFoundationFactory = new HttpFoundationFactory();
$symfonyRequest = $httpFoundationFactory->createRequest($psrRequest);
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
/** @var $psrResponse \Psr\Http\Message\ResponseInterface */
$httpFoundationFactory = new HttpFoundationFactory();
$symfonyResponse = $httpFoundationFactory->createResponse($psrResponse);
Credits: StackPHP
In other languages:
In PHP:
function myStratigilityMiddleware(
\Psr\Http\Message\ServerRequestInterface $request,
\Psr\Http\Message\ResponseInterface $response,
callable $next = null
) {
$response->getBody()->write('Hello from Stratigility');
return $next($req, $res);
}
class MyController {
public function indexAction(\Psr\Http\Message\ServerRequestInterface $request)
{
$response = new \Zend\Diactoros\Response();
return myStratigilityMiddleware($request, $response, function ($req, $res) {
return $res;
});
}
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$httpFoundationFactory = new HttpFoundationFactory();
$diactorosFactory = new DiactorosFactory();
myStratigilityMiddleware(
$diactorosFactory->createRequest($event->getRequest()),
$diactorosFactory->createResponse($event->getResponse()),
function ($req, $res) use ($event) {
$event->setResponse($httpFoundationFactory->createResponse($res));
}
);
}