Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Psr Http Message Bridge Laravel Package

symfony/psr-http-message-bridge

Symfony PSR-7 Bridge integrates PSR-7 HTTP messages with Symfony’s HttpFoundation. Convert requests and responses between PSR-7 implementations and Symfony components to ease interoperability with middleware and libraries.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/psr-http-message-bridge
    

    No additional configuration is required—this is a zero-config package.

  2. First Use Case: Convert between Symfony’s HttpFoundation (e.g., Request, Response) and PSR-7 (Psr\Http\Message\* interfaces). Example:

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    use Psr\Http\Message\ServerRequestInterface;
    
    $request = Request::createFromGlobals();
    $psrFactory = new PsrHttpFactory();
    $psrRequest = $psrFactory->createRequest($request); // PSR-7 Request
    
  3. Where to Look First:

    • Symfony PSR-7 Component Docs (official reference).
    • src/Factory/ for core conversion logic (PsrHttpFactory, HttpFoundationFactory).
    • tests/ for edge-case examples (e.g., handling cookies, headers, or streams).

Implementation Patterns

Core Workflows

  1. Bidirectional Conversion: Use PsrHttpFactory (PSR-7 → Symfony) and HttpFoundationFactory (Symfony → PSR-7) for seamless integration.

    $psrFactory = new PsrHttpFactory();
    $symfonyFactory = new HttpFoundationFactory();
    
    // PSR-7 → Symfony
    $symfonyRequest = $symfonyFactory->createRequest($psrRequest);
    
    // Symfony → PSR-7
    $psrResponse = $psrFactory->createResponse($symfonyResponse);
    
  2. Middleware Integration: Bridge PSR-15 middleware (e.g., from zend-stratigility or league/plates) with Laravel’s middleware stack.

    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Server\RequestHandlerInterface;
    
    $psrMiddleware = new Psr15Middleware();
    $handler = new class implements RequestHandlerInterface {
        public function handle(ServerRequestInterface $request): ResponseInterface {
            return new Response();
        }
    };
    
    $psrResponse = $psrMiddleware->process($psrRequest, $handler);
    $symfonyResponse = $symfonyFactory->createResponse($psrResponse);
    
  3. Stream Handling: Convert Symfony’s StreamInterface (e.g., file uploads) to PSR-7 StreamInterface:

    $symfonyStream = $request->getClientOriginalExtension('file');
    $psrStream = $psrFactory->createStream($symfonyStream);
    
  4. Laravel-Specific Patterns:

    • Request/Response Wrapping: Extend Laravel’s Illuminate\Http\Request/Response with PSR-7 methods via traits or decorators.
      use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
      
      class Psr7Request extends Request {
          protected $psrFactory;
      
          public function __construct(Request $request) {
              $this->psrFactory = new PsrHttpFactory();
          }
      
          public function toPsr7(): ServerRequestInterface {
              return $this->psrFactory->createRequest($this);
          }
      }
      
    • PSR-7 Middleware in Laravel: Register PSR-15 middleware in Laravel’s Kernel.php:
      protected function psrMiddleware(): array {
          return [
              \Symfony\Component\HttpKernel\Middleware\CheckReferer::class,
          ];
      }
      
      public function boot() {
          $this->app->make(\Illuminate\Contracts\Http\Kernel::class)->push(
              app()->make(\Symfony\Component\HttpKernel\HttpKernel::class)
          );
      }
      

Gotchas and Tips

Pitfalls

  1. Header Case Sensitivity: PSR-7 headers are case-insensitive, but Symfony’s HttpFoundation preserves original case. Use normalizeHeaderName() if consistency is critical:

    $psrRequest->getHeaderLine('Content-Type'); // Normalized
    
  2. Stream Detachment: PSR-7 streams must not be detached after conversion. Symfony’s streams may behave differently:

    // ❌ Avoid detaching PSR-7 streams post-conversion
    $psrStream->detach(); // May break Symfony's internal state
    
  3. Cookie Handling: Symfony’s Cookie class differs from PSR-7’s Cookie interface. Use PsrHttpFactory::createCookie() for explicit conversion:

    $symfonyCookie = new Cookie('name', 'value');
    $psrCookie = $psrFactory->createCookie($symfonyCookie);
    
  4. Uploaded Files: PSR-7’s UploadedFileInterface is a subset of Symfony’s UploadedFile. Ensure all methods (e.g., moveTo()) are handled:

    $symfonyFile = $request->file('upload');
    $psrFile = $psrFactory->createUploadedFile($symfonyFile);
    // $psrFile->moveTo() may not work; use Symfony's original methods if needed.
    

Debugging Tips

  1. Validate PSR-7 Compliance: Use Psr\Http\Message\MessageInterface::getBody() to inspect streams/headers:

    $psrRequest->getBody()->rewind();
    $headers = iterator_to_array($psrRequest->getHeaders());
    
  2. Logging Conversions: Log before/after conversion to catch silent failures:

    \Log::debug('Symfony Request', [
        'method' => $request->getMethod(),
        'uri' => $request->getUri(),
    ]);
    
  3. Extension Points:

    • Override PsrHttpFactory to customize conversions (e.g., modify headers):
      class CustomPsrHttpFactory extends PsrHttpFactory {
          public function createRequest(Request $request): ServerRequestInterface {
              $psrRequest = parent::createRequest($request);
              $psrRequest = $psrRequest->withHeader('X-Custom', 'value');
              return $psrRequest;
          }
      }
      
    • Use HttpFoundationFactory::createResponse() to inject PSR-7-specific logic.

Performance Quirks

  • Avoid Repeated Conversions: Cache converted objects if used frequently (e.g., in a request-scoped service):
    $psrRequest = app()->bound('psr.request')
        ?? app()->instance('psr.request', $psrFactory->createRequest(request()));
    
  • Stream Copying: PSR-7 streams are immutable. Copy streams if multiple operations are needed:
    $stream = $psrRequest->getBody();
    $streamCopy = fopen('php://temp', 'r+');
    stream_copy_to_stream($stream, $streamCopy);
    $streamCopy->rewind();
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai