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

Http Message Laravel Package

psr/http-message

PSR-7 HTTP message interfaces for PHP (Request/Response, Streams, URIs, UploadedFiles). Defines common contracts only—no concrete implementation. Ideal for framework-agnostic middleware and libraries needing interoperable HTTP message types.

View on GitHub
Deep Wiki
Context7

Getting Started

psr/http-message is not a standalone implementation—it’s a set of PSR-7 interfaces defining how HTTP messages (requests, responses, streams, URIs, etc.) should behave. To use it day-to-day:

  1. Require a PSR-7 implementation: Install a concrete implementation like guzzlehttp/psr7, nyholm/psr7, or laminas/laminas-diactoros (e.g., composer require guzzlehttp/psr7).
  2. Type-hint against interfaces: In your code (middleware, services, controllers), accept and return types like ServerRequestInterface, ResponseInterface, etc.—not implementations.
  3. Start with the most common interfaces: Focus on ServerRequestInterface (incoming request), ResponseInterface (outgoing response), and MessageInterface (shared methods).
  4. Read the cheat sheet: Refer to PSR7-Interfaces.md for quick method lookup—especially headers, body, URI, and attribute methods.

First real use case: Build a middleware that inspects request headers and returns a 400 if a required header is missing:

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

function validateApiKey(Request $request, callable $next): Response
{
    if (!$request->hasHeader('X-API-Key')) {
        return (new Response())->withStatus(400, 'Missing API key');
    }
    return $next($request);
}

Implementation Patterns

  • Immutable message construction: PSR-7 objects are immutable. Always use with*() methods to return new instances:

    $response = $response->withStatus(201);
    $response = $response->withHeader('Location', '/users/123');
    

    (Don’t mutate in place.)

  • Body handling best practices:

    • Prefer getBody() once and reuse the reference:
      $body = $response->getBody();
      $body->write(json_encode(['success' => true]));
      $body->rewind();
      
    • For streamed output (e.g., large files), inject a stream from a file resource:
      $stream = $response->getBody()->detach();
      $response = $response->withBody(new Stream(fopen('/large.csv', 'r')));
      
  • URI manipulation: Build or modify URIs with UriInterface—avoid string concatenation:

    $uri = $request->getUri()->withPath('/api/v2/users');
    $newRequest = $request->withUri($uri);
    
  • Attribute-driven workflows: Use ServerRequestInterface::getAttribute()/withAttribute() to pass data through middleware (e.g., authenticated user, route params):

    // In auth middleware
    $request = $request->withAttribute('user', $user);
    
    // In controller
    $user = $request->getAttribute('user');
    
  • Uploaded files: Normalize handling via UploadedFileInterface—never access $_FILES directly:

    $uploadedFiles = $request->getUploadedFiles();
    $avatar = $uploadedFiles['avatar'] ?? null;
    if ($avatar && $avatar->getError() === UPLOAD_ERR_OK) {
        $avatar->moveTo('/uploads/' . $avatar->getClientFilename());
    }
    
  • Middleware interop: The interface is foundational for PSR-15/PSR-15-like middleware stacks (e.g., Slim, Zend Expressive, custom stacks).


Gotchas and Tips

  • Immutable ≠ intuitive: It’s easy to forget to reassign the result of with*() calls:

    // ❌ No effect: response unchanged
    $response->withStatus(201);
    
    // ✅ Correct
    $response = $response->withStatus(201);
    
  • Headers are arrays internally: getHeader() returns an array (e.g., ['text/html']), getHeaderLine() returns a comma-separated string ('text/html'). Don’t assume single items.

  • Body streams are read/write by default: Many implementations use memory streams—write then rewind() before reading. getContents() starts at the current position.

  • getParsedBody() vs getParsedBody() && withParsedBody(): Often empty until parsed by middleware (e.g., slim/psr7 auto-parses JSON/URL-encoded bodies; others require guzzlehttp/psr7’s RequestFactory or middleware).

  • No built-in implementation: This package only provides interfaces. You must choose and trust an implementation. Check compatibility (e.g., nyholm/psr7 is lightweight and HHVM-compatible; guzzlehttp/psr7 is battle-tested but heavier).

  • Debugging tip: Use (string) $uri, (string) $body, or var_dump(get_class($message)) to inspect concrete types and contents quickly.

  • Extension points: Implement your own StreamInterface for custom storage (e.g., encrypting streams, S3-backed streams) or extend ServerRequestInterface implementations to add domain-specific methods (e.g., getJwtClaims()).

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