symfony/psr-http-message-bridge
Symfony PSR-7 Bridge integrates PSR-7 HTTP messages with Symfony. Convert between Symfony HttpFoundation requests/responses and PSR-7 implementations, enabling interoperability with PSR-7 middleware, libraries, and frameworks.
Installation:
composer require symfony/psr-http-message-bridge
Ensure compatibility with Laravel’s PHP version (e.g., PHP 8.1+ for Symfony 6.x/7.x).
First Use Case:
Convert a Laravel Request to a PSR-7 ServerRequest for use with PSR-15 middleware:
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Psr\Http\Message\ServerRequestInterface;
$symfonyRequest = SymfonyRequest::createFromGlobals();
$psrFactory = new PsrHttpFactory();
$psrRequest = $psrFactory->createRequest($symfonyRequest);
Where to Look First:
PsrHttpFactory and HttpFoundationFactory classes for bidirectional conversions.Illuminate\Http\Request vs. Symfony’s Request differences (e.g., cookie handling, file uploads).Middleware Integration: Wrap PSR-15 middleware for Laravel routes:
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
$psrFactory = new PsrHttpFactory();
$middleware = new YourPsr15Middleware();
$symfonyRequest = SymfonyRequest::createFromGlobals();
$psrRequest = $psrFactory->createRequest($symfonyRequest);
$response = $middleware->process($psrRequest, function () {
return new SymfonyResponse(); // PSR-7 Response
});
$symfonyResponse = $psrFactory->createResponse($response);
$symfonyResponse->send();
API Gateway Pattern: Convert PSR-7 responses from Symfony microservices to Laravel-compatible formats:
$psrResponse = $symfonyMicroservice->handle($psrRequest);
$symfonyResponse = $psrFactory->createResponse($psrResponse);
return new LaravelResponse($symfonyResponse->getContent());
Testing: Generate PSR-7 mocks for Symfony components in Laravel tests:
$psrRequest = (new PsrHttpFactory())
->createRequest(SymfonyRequest::create('/test', 'GET'));
$this->assertInstanceOf(ServerRequestInterface::class, $psrRequest);
Dependency Injection: Bind the factory to Laravel’s container for reuse:
$this->app->singleton(PsrHttpFactory::class, function () {
return new PsrHttpFactory();
});
Laravel Middleware:
Extend BaseMiddleware to convert PSR-7 ↔ Symfony:
public function handle($request, Closure $next) {
$psrRequest = $this->psrFactory->createRequest($request);
$psrResponse = $next($psrRequest);
return $this->psrFactory->createResponse($psrResponse);
}
File Uploads:
Use Symfony\Component\HttpFoundation\File\UploadedFile for PSR-7 UploadedFileInterface:
$uploadedFile = $psrRequest->getUploadedFiles()['file'];
$symfonyFile = new UploadedFile(
$uploadedFile->getClientFilename(),
$uploadedFile->getClientMediaType()
);
Cookie Partitioning:
__Host-, __Secure-) may still cause issues in older versions.SymfonyRequest before conversion.Stream Handling:
StreamInterface) may not map cleanly to Laravel’s Symfony\Component\HttpFoundation\File\UploadedFile.Symfony\Component\HttpFoundation\FileBag for complex file handling.Autoloading Conflicts:
HttpFoundation may conflict with Laravel’s bundled components.composer require symfony/http-foundation explicitly to avoid version mismatches.Server Parameters:
$request->server() vs. Symfony’s $request->server may differ in key names (e.g., HTTP_HOST vs. SERVER_NAME).$symfonyRequest->server->set('HTTP_HOST', $request->server('HTTP_HOST'));
Invalid PSR-7 Objects: Validate responses before conversion:
if (!$psrResponse instanceof ResponseInterface) {
throw new \RuntimeException('Invalid PSR-7 response');
}
Cookie Serialization:
Use Symfony\Component\Serializer\SerializerInterface to debug cookie serialization issues:
$serializer = new Serializer();
$cookies = $serializer->serialize($psrRequest->getCookieParams(), 'json');
Custom Factories:
Extend PsrHttpFactory to handle Laravel-specific cases:
class LaravelPsrHttpFactory extends PsrHttpFactory {
public function createRequest(Request $laravelRequest) {
$symfonyRequest = SymfonyRequest::createFromGlobals();
$symfonyRequest->query->replace($laravelRequest->query());
return parent::createRequest($symfonyRequest);
}
}
PSR-15 Middleware: Create a Laravel service provider to register PSR-15 middleware:
public function register() {
$this->app->bind(MiddlewareInterface::class, function () {
return new YourPsr15Middleware();
});
}
Testing Helpers: Add a trait for test conversions:
trait PsrHttpTestTrait {
protected function toPsr7(Request $request) {
return (new PsrHttpFactory())->createRequest($request);
}
}
Laravel’s Request vs. Symfony Request:
Request extends Symfony\Component\HttpFoundation\Request, but methods like ip() or userAgent() may behave differently.SymfonyRequest::createFromGlobals() as a baseline for consistency.Case Sensitivity:
Request preserves original case. Normalize headers before conversion:
$psrRequest = $psrRequest->withHeader(
'Content-Type',
$symfonyRequest->headers->get('Content-Type')
);
How can I help you explore Laravel packages today?