loophp/psr-http-message-bridge-bundle
Symfony bundle that bridges PSR-7 HTTP messages with Symfony’s HttpFoundation, enabling smooth interop between PSR-7 libraries and Symfony apps. Provides converters/adapters to translate requests and responses in both directions.
Installation
composer require loophp/psr-http-message-bridge-bundle:^1.3
Add to config/bundles.php (Symfony 5/6/7/8 compatible):
return [
// ...
Loophp\PsrHttpMessageBridgeBundle\LoophpPsrHttpMessageBridgeBundle::class => ['all' => true],
];
First Use Case (Symfony 8 Compatible)
Convert a Symfony Request to a PSR-7 ServerRequest:
use Loophp\PsrHttpMessageBridge\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
$psrRequest = PsrHttpFactory::createRequest($request);
Where to Look First
config/packages/loophp_psr_http_message_bridge.yaml (auto-generated for Symfony 8).PsrHttpFactory and PsrStreamFactory in Loophp\PsrHttpMessageBridge\Factory (now fully compatible with Symfony 8 components).Request/Response Conversion (Symfony 8)
Bridge Symfony’s Request/Response ↔ PSR-7 ServerRequest/Response:
// Symfony → PSR-7 (Symfony 8)
$psrRequest = PsrHttpFactory::createRequest($symfonyRequest);
$psrResponse = PsrHttpFactory::createResponse($symfonyResponse);
// PSR-7 → Symfony (Symfony 8)
$symfonyRequest = PsrHttpFactory::createRequest($psrRequest);
$symfonyResponse = PsrHttpFactory::createResponse($psrResponse);
Middleware Integration (PSR-15) Use PSR-15 middleware with Symfony 8:
use Loophp\PsrHttpMessageBridge\Bridge\Symfony\Psr15Middleware;
use Psr\Http\Server\MiddlewareInterface;
$psrMiddleware = new class implements MiddlewareInterface {
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
return $handler->handle($request);
}
};
$symfonyMiddleware = new Psr15Middleware($psrMiddleware);
Stream Handling (Symfony 8 Streams)
Convert Symfony’s StreamedResponse ↔ PSR-7 StreamInterface:
$psrStream = PsrHttpFactory::createStream($symfonyStream);
$symfonyStream = PsrHttpFactory::createStream($psrStream);
Dependency Injection (Symfony 8)
Register factories as services in services.yaml (Symfony 8 compatible):
services:
Loophp\PsrHttpMessageBridge\Factory\PsrHttpFactory: ~
Loophp\PsrHttpMessageBridge\Factory\PsrStreamFactory: ~
Custom PSR-7 Implementations (Symfony 8)
Override default factories (e.g., for Guzzle’s Psr7):
$factory = new PsrHttpFactory(new \GuzzleHttp\Psr7\Factory\Psr17Factory());
Symfony 8 Component Changes
Request/Response may have stricter type hints. Ensure your PSR-7 objects comply:
// Verify PSR-7 compliance
assert($psrRequest instanceof \Psr\Http\Message\ServerRequestInterface);
assert($psrResponse instanceof \Psr\Http\Message\ResponseInterface);
Circular References in Streams (Symfony 8)
SymfonyStream → PSR-7 → SymfonyStream).PsrHttpFactory::createStream() only once per stream.Uploaded Files (Symfony 8)
UploadedFile is not directly convertible to PSR-7. Use PsrHttpFactory::createUploadedFile():
$psrUploadedFile = PsrHttpFactory::createUploadedFile($symfonyUploadedFile);
Server Params Mismatch (Symfony 8)
SERVER params may differ from Symfony’s $_SERVER. Verify with:
$psrRequest->getServerParams() === $symfonyRequest->server->all();
Deprecated Methods (Symfony 8)
PsrHttpFactory::createRequestFromGlobals() (uses $_SERVER, $_GET, etc.). Use Request::createFromGlobals() + bridge instead.Verify Conversions (Symfony 8)
$symfonyRequest = PsrHttpFactory::createRequest($psrRequest);
assert($symfonyRequest->query->all() === $psrRequest->getQueryParams());
Log PSR-7 Objects (Symfony 8)
Use var_export() or json_encode() for debugging:
$psrRequest->getBody()->rewind();
$body = $psrRequest->getBody()->getContents();
Check for Factory Overrides (Symfony 8) If behavior is unexpected, ensure no custom factories are overriding defaults:
$factory = $container->get('loophp_psr_http_message_bridge.factory.psr_http');
Custom Factories (Symfony 8)
Extend PsrHttpFactory to support additional PSR-7 implementations:
class CustomPsrHttpFactory extends PsrHttpFactory {
public function createRequest(Symfony\Component\HttpFoundation\Request $request): \Psr\Http\Message\ServerRequestInterface {
// Custom logic for Symfony 8
}
}
Event Listeners (Symfony 8) Hook into Symfony 8 events to modify conversions (e.g., add default headers):
// config/services.yaml
services:
App\EventListener\PsrHttpListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
Configuration Overrides (Symfony 8)
Customize bundle behavior via config/packages/loophp_psr_http_message_bridge.yaml:
loophp_psr_http_message_bridge:
default_psr17_factory: 'GuzzleHttp\Psr7\Factory\Psr17Factory'
Testing (Symfony 8) Mock PSR-7 objects in tests:
$psrRequest = $this->createMock(\Psr\Http\Message\ServerRequestInterface::class);
$psrRequest->method('getMethod')->willReturn('GET');
Symfony 8-Specific Notes
#[Route('/example', methods: ['GET'])]
public function example(ServerRequestInterface $request): ResponseInterface {
return PsrHttpFactory::createResponse(new Response());
}
HttpClient, ensure PSR-7 objects are properly converted when interacting with middleware.How can I help you explore Laravel packages today?