Less than 2 weeks ago, the PHP community roundly accepted PSR-7, giving PHP a common set of HTTP Message Interfaces. This has huge potential for interoperability and standardization across all of PHP. This is especially true for middleware: functions that hook into the request-response process. In the future, a middleware written around these new interfaces could be used in any framework.

Introducing the PSR HTTP Message Bridge

Today, a huge number of projects use Symfony's Request and Response classes (via the HttpFoundation component), including Laravel, Drupal 8 and StackPHP. This has given us a base for HTTP Message standardization over the last 4 years, before the community was ready to discuss an official interface. Promoting interoperability is at the core of Symfony's philosophy.

For that reason, we're thrilled to announce the 0.1 release of the PSR HTTP Message Bridge: a library that can convert Symfony Request and Response objects to PSR-7 compatible objects and back. This means that once there are middleware written for PSR-7, applications using HttpFoundation will be compatible.

Converting from a PSR-7 object to HttpFoundation is as easy as this:

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;

$httpFoundationFactory = new HttpFoundationFactory();

// convert a Request
// $psrRequest is an instance of Psr\Http\Message\ServerRequestInterface
$symfonyRequest = $httpFoundationFactory->createRequest($psrRequest);

// convert a Response
// $psrResponse is an instance of Psr\Http\Message\ResponseInterface
$symfonyResponse = $httpFoundationFactory->createResponse($psrResponse);

You can also convert from an HttpFoundation object to PSR-7. For this, the bridge uses Diactoros - an early PSR-7 implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$psr7Factory = new DiactorosFactory();

// convert a Request
$symfonyRequest = Request::createFromGlobals();
$psrRequest = $psr7Factory->createRequest($symfonyRequest);

// convert a Response
$symfonyResponse = new Response('Content');
$psrResponse = $psr7Factory->createResponse($symfonyResponse);

This allows projects to take advantage of PSR-7 immediately, but without breaking backwards compatibility. That's really important: Symfony has a proud backwards compatibility promise that won't be broken.

Thanks a lot to dunglas (a core team member), who did a lot of the initial work on this library. Documentation is in progress and the bridge currently has some edge cases related to large request and response bodies. But this is a fantastic start, and we're thrilled about it.

RequestInterface and ResponseInterface in the Symfony Framework

In the Symfony Framework, a controller usually receives Symfony's Request object and returns a Symfony Response object. But now, you can choose to receive and return PSR-7 Request and Response objects instead, thanks to a small patch to the SensioFrameworkExtraBundle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)
    {
        // Interact with the PSR-7 request

        $response = new Response();
        // Interact with the PSR-7 response

        return $response;
    }
}

This is available in the latest release of SensioFrameworkExtraBundle, which is compatible with every maintained version of Symfony (2.3+). So if this is something you want to do in your controllers, you can start doing it immediately!

Published in #Symfony