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 Steps

  1. Installation: Add the package via Composer in your Laravel project:

    composer require symfony/psr-http-message-bridge
    

    Laravel already includes symfony/http-foundation, so no additional dependencies are required.

  2. First Use Case: Convert a Laravel Request to a PSR-7 ServerRequest for use with PSR-7 middleware or libraries:

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


Implementation Patterns

Usage Patterns

  1. Middleware Integration: Convert Laravel middleware to PSR-15 middleware for use in non-Laravel environments (e.g., Slim, Laminas):

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Server\MiddlewareInterface;
    use Psr\Http\Server\RequestHandlerInterface;
    
    class LaravelMiddleware implements MiddlewareInterface {
        public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
            $psrFactory = new PsrHttpFactory();
            $laravelRequest = $psrFactory->createRequest($request);
            $laravelResponse = app()->handle($laravelRequest); // Laravel's handle method
            return $psrFactory->createResponse($laravelResponse);
        }
    }
    
  2. HTTP Client Abstraction: Use PSR-7 responses with Laravel’s HTTP client (Guzzle-based):

    use Illuminate\Support\Facades\Http;
    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    
    $response = Http::get('https://api.example.com');
    $psrFactory = new PsrHttpFactory();
    $psrResponse = $psrFactory->createResponse($response);
    
  3. Testing: Mock PSR-7 requests/responses in Laravel tests:

    use Nyholm\Psr7\Factory\Psr17Factory;
    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    
    $psrFactory = new Psr17Factory();
    $psrRequest = $psrFactory->createServerRequest('GET', '/test');
    $symfonyFactory = new PsrHttpFactory();
    $laravelRequest = $symfonyFactory->createRequest($psrRequest);
    
    // Use $laravelRequest in Laravel test cases
    

Workflows

  1. Request/Response Conversion Workflow:

    • Convert incoming Laravel Request to PSR-7 ServerRequest for PSR-7 middleware.
    • Process the request with PSR-15 middleware.
    • Convert the PSR-7 Response back to Laravel Response for Laravel’s response handling.
  2. API Resource Sharing: Share API resources between Laravel and PSR-7-compliant services by converting responses:

    $laravelResponse = response()->json(['data' => 'example']);
    $psrFactory = new PsrHttpFactory();
    $psrResponse = $psrFactory->createResponse($laravelResponse);
    // Send $psrResponse to a PSR-7-compliant service
    
  3. Event-Driven Architectures: Use PSR-7 messages in event-driven workflows (e.g., with Laravel Queues or message brokers):

    $psrRequest = $psrFactory->createRequest(request());
    // Dispatch $psrRequest to a message broker or queue
    

Integration Tips

  1. Service Provider Binding: Bind the bridge factory in Laravel’s service container for reusable conversions:

    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    use Illuminate\Support\ServiceProvider;
    
    class PsrHttpServiceProvider extends ServiceProvider {
        public function register() {
            $this->app->singleton(PsrHttpFactory::class, function () {
                return new PsrHttpFactory();
            });
        }
    }
    

    Then inject PsrHttpFactory into controllers/middleware:

    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    
    public function __construct(private PsrHttpFactory $psrFactory) {}
    
  2. Middleware Pipeline: Integrate PSR-15 middleware into Laravel’s pipeline by wrapping it in a Laravel-compatible middleware:

    use Psr\Http\Server\MiddlewareInterface;
    use Closure;
    
    class PsrMiddlewareWrapper {
        public function __construct(private MiddlewareInterface $psrMiddleware) {}
    
        public function handle($request, Closure $next) {
            $psrFactory = app(PsrHttpFactory::class);
            $psrRequest = $psrFactory->createRequest($request);
            $psrResponse = $this->psrMiddleware->process($psrRequest, new PsrHandler($next));
            return $psrFactory->createResponse($psrResponse);
        }
    }
    
  3. Testing Utilities: Create helper methods for test conversions:

    use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
    
    if (!function_exists('psrRequest')) {
        function psrRequest(string $method, string $uri, array $server = []): ServerRequestInterface {
            $psrFactory = new PsrHttpFactory();
            $laravelRequest = Request::create($uri, $method, [], [], [], $server);
            return $psrFactory->createRequest($laravelRequest);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Cookie Handling:

    • Laravel’s Cookie class and PSR-7’s CookieJarInterface may handle partitioned cookies differently. Ensure cookie logic is tested after conversion.
    • Fix: Use the bridge’s built-in cookie conversion, but validate edge cases:
      $psrRequest = $psrFactory->createRequest($laravelRequest);
      $cookies = $psrRequest->getCookieParams(); // May differ from Laravel's cookie bag
      
  2. File Uploads:

    • PSR-7’s UploadedFileInterface and Symfony’s UploadedFile may differ in stream handling. Large file uploads might behave unexpectedly.
    • Fix: Explicitly handle file streams post-conversion:
      $uploadedFile = $psrRequest->getUploadedFiles()['file'];
      $stream = $uploadedFile->getStream();
      // Rewind or process stream as needed
      
  3. Server Request Attributes:

    • Laravel’s ServerRequest extends Symfony\Component\HttpFoundation\Request, which is not a PSR-7 ServerRequestInterface. Some PSR-7 middleware may expect strict compliance.
    • Fix: Use the bridge’s conversion but test middleware that relies on PSR-7-specific attributes:
      $psrRequest = $psrFactory->createRequest($laravelRequest);
      $attributes = $psrRequest->getAttributes(); // May not include all Laravel-specific data
      
  4. Response Status Codes:

    • Laravel’s Response and PSR-7 ResponseInterface handle status codes similarly, but custom responses might differ. Ensure status codes are preserved:
      $laravelResponse = response()->setStatusCode(403);
      $psrResponse = $psrFactory->createResponse($laravelResponse);
      assert($psrResponse->getStatusCode() === 403);
      
  5. Server Variables:

    • Some $_SERVER variables (e.g., PHP_SELF, REQUEST_METHOD) may not map perfectly to PSR-7’s ServerRequestInterface.
    • Fix: Manually set critical server variables if needed:
      $psrRequest = $psrFactory->createRequest($laravelRequest)
          ->withServerParams(array_merge(
              $psrRequest->getServerParams(),
              ['REQUEST_METHOD' => 'GET']
          ));
      

Debugging

  1. Conversion Validation:

    • Verify conversions by logging request/response attributes:
      $psrRequest = $psrFactory->createRequest($laravelRequest);
      \Log::debug('PSR-7 Server Params:', $psrRequest->getServerParams());
      \Log::debug('PSR-7 Headers:', $psrRequest->getHeaders());
      
  2. Middleware Debugging:

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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony