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. Convert between Symfony HttpFoundation requests/responses and PSR-7 implementations, enabling interoperability with PSR-7 middleware, libraries, and frameworks.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. 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).

  2. 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);
    
  3. Where to Look First:

    • Symfony PSR-7 Documentation for conversion methods.
    • PsrHttpFactory and HttpFoundationFactory classes for bidirectional conversions.
    • Laravel’s Illuminate\Http\Request vs. Symfony’s Request differences (e.g., cookie handling, file uploads).

Implementation Patterns

Core Workflows

  1. 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();
    
  2. 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());
    
  3. Testing: Generate PSR-7 mocks for Symfony components in Laravel tests:

    $psrRequest = (new PsrHttpFactory())
        ->createRequest(SymfonyRequest::create('/test', 'GET'));
    $this->assertInstanceOf(ServerRequestInterface::class, $psrRequest);
    

Integration Tips

  • 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()
    );
    

Gotchas and Tips

Pitfalls

  1. Cookie Partitioning:

    • Fixed in v7.1.4, but partitioned cookies (e.g., __Host-, __Secure-) may still cause issues in older versions.
    • Workaround: Explicitly set cookie domains/path in SymfonyRequest before conversion.
  2. Stream Handling:

    • PSR-7 streams (StreamInterface) may not map cleanly to Laravel’s Symfony\Component\HttpFoundation\File\UploadedFile.
    • Tip: Use Symfony\Component\HttpFoundation\FileBag for complex file handling.
  3. Autoloading Conflicts:

    • Symfony’s HttpFoundation may conflict with Laravel’s bundled components.
    • Solution: Use composer require symfony/http-foundation explicitly to avoid version mismatches.
  4. Server Parameters:

    • Laravel’s $request->server() vs. Symfony’s $request->server may differ in key names (e.g., HTTP_HOST vs. SERVER_NAME).
    • Fix: Normalize server params before conversion:
      $symfonyRequest->server->set('HTTP_HOST', $request->server('HTTP_HOST'));
      

Debugging

  • 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');
    

Extension Points

  1. 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);
        }
    }
    
  2. 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();
        });
    }
    
  3. Testing Helpers: Add a trait for test conversions:

    trait PsrHttpTestTrait {
        protected function toPsr7(Request $request) {
            return (new PsrHttpFactory())->createRequest($request);
        }
    }
    

Configuration Quirks

  • Laravel’s Request vs. Symfony Request:

    • Laravel’s Request extends Symfony\Component\HttpFoundation\Request, but methods like ip() or userAgent() may behave differently.
    • Tip: Use SymfonyRequest::createFromGlobals() as a baseline for consistency.
  • Case Sensitivity:

    • PSR-7 headers are case-insensitive, but Symfony’s Request preserves original case. Normalize headers before conversion:
      $psrRequest = $psrRequest->withHeader(
          'Content-Type',
          $symfonyRequest->headers->get('Content-Type')
      );
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport