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

Psr7 Laravel Package

guzzlehttp/psr7

Full PSR-7 HTTP message implementation from Guzzle: request/response objects, URI and stream support, plus stream decorators (buffering, caching, appending, dropping) and utilities like query string parsing. Composer install; v2 supports PHP 7.2.5–8.5.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require guzzlehttp/psr7
    

    Add to composer.json under require or require-dev depending on your needs.

  2. First Use Case: Create a basic HTTP request/response using PSR-7 messages:

    use GuzzleHttp\Psr7\Request;
    use GuzzleHttp\Psr7\Response;
    
    $request = new Request('GET', 'https://example.com');
    $response = new Response(200, [], 'Hello, World!');
    
  3. Key Classes to Know:

    • Request, Response: Core PSR-7 message interfaces.
    • StreamInterface: For handling request/response bodies.
    • Utils: Static helper methods (e.g., streamFor, copyToString).
  4. Where to Look First:

    • PSR-7 Specification for interface contracts.
    • GuzzleHttp\Psr7\Utils for utility methods (e.g., stream creation, query parsing).
    • Stream decorators (e.g., AppendStream, LimitStream) for advanced use cases.

Implementation Patterns

Core Workflows

1. Request/Response Handling

  • Creating Requests:
    $request = new Request('POST', '/api/users', [
        'Content-Type' => 'application/json',
    ], json_encode(['name' => 'John']));
    
  • Creating Responses:
    $response = new Response(201, [], json_encode(['id' => 123]));
    

2. Stream Manipulation

  • From Strings/Resources:
    $stream = Utils::streamFor('Hello');
    $fileStream = Utils::streamFor(fopen('file.txt', 'r'));
    
  • Decorating Streams:
    $limitedStream = new LimitStream($stream, 100); // Read first 100 bytes
    $appendedStream = new AppendStream([$stream1, $stream2]);
    
  • Copying Streams:
    Utils::copyToString($stream); // Convert stream to string
    Utils::copyToStream($source, $destination); // Stream-to-stream copy
    

3. Query and URI Handling

  • Parsing Queries:
    $query = Query::parse('foo=bar&baz=qux');
    // ['foo' => 'bar', 'baz' => 'qux']
    
  • Building Queries:
    $queryString = Query::build(['foo' => 'bar', 'baz' => 'qux']);
    // 'foo=bar&baz=qux'
    

4. Modifying Requests

  • Cloning and Updating:
    $modified = Utils::modifyRequest($request, [
        'method' => 'PUT',
        'set_headers' => ['X-Custom' => 'Value'],
    ]);
    

5. Static Utilities

  • Hashing Streams:
    $hash = Utils::hash($stream, 'md5');
    
  • Rewinding Bodies:
    Utils::rewindBody($response);
    

Integration Tips

Laravel-Specific Patterns

  1. HTTP Clients (Guzzle Integration):

    • Use guzzlehttp/psr7 with Laravel's HTTP client (e.g., Http::asJson()) for custom request/response handling.
    • Example: Override default responses with PSR-7 streams:
      $response = Http::withOptions(['decode_content' => false])->get('...');
      $stream = $response->getBody();
      
  2. File Uploads/Downloads:

    • Use LazyOpenStream for lazy file handling:
      $stream = new LazyOpenStream(storage_path('file.txt'), 'r');
      
    • Use LimitStream for chunked uploads:
      $chunkedStream = new LimitStream($fileStream, 1024 * 1024); // 1MB chunks
      
  3. Middleware:

    • Decorate streams in middleware to log, transform, or validate:
      $kernel->pushMiddleware(function ($request, $next) {
          $request = Utils::modifyRequest($request, [
              'set_headers' => ['X-Processed' => 'true'],
          ]);
          return $next($request);
      });
      
  4. Testing:

    • Mock PSR-7 messages in PHPUnit:
      $mockStream = $this->createMock(StreamInterface::class);
      $mockStream->method('read')->willReturn('mocked');
      $request = new Request('GET', '/', [], $mockStream);
      
  5. API Responses:

    • Convert PSR-7 responses to Laravel's Illuminate\Http\Response:
      $psrResponse = new Response(200, [], '{"data": "..."}');
      return response($psrResponse->getBody(), $psrResponse->getStatusCode(), $psrResponse->getHeaders());
      

Gotchas and Tips

Pitfalls

  1. Stream Ownership:

    • Issue: Closing a stream (e.g., $stream->close()) may break decorators or upstream consumers.
    • Fix: Use NoSeekStream or CachingStream to manage lifecycle explicitly.
  2. Memory Leaks:

    • Issue: CachingStream buffers data in memory/disk. Large streams can exhaust resources.
    • Fix: Set a highWaterMark or use LimitStream to cap size.
  3. Seekable vs. Non-Seekable Streams:

    • Issue: Some streams (e.g., PumpStream, FnStream) are non-seekable. Operations like seek() or rewind() will fail.
    • Fix: Use CachingStream to wrap non-seekable streams or avoid seeking.
  4. Query Parsing Quirks:

    • Issue: Query::parse() does not handle nested arrays (e.g., foo[a]=1&foo[b]=2 becomes ['foo[a]' => '1']).
    • Fix: Pre-process arrays or use http_build_query() for nested structures.
  5. Stream Decorator Order:

    • Issue: Decorators are applied in reverse order (innermost first). Misordering can lead to unexpected behavior.
    • Fix: Test decorator stacks incrementally:
      $stream = new LimitStream(new CachingStream($originalStream), 1024);
      
  6. UTF-8 Assumptions:

    • Issue: Some methods (e.g., readLine) assume UTF-8 encoding. Non-UTF-8 streams may break.
    • Fix: Encode/decode streams explicitly if needed:
      $utf8Stream = new TransformStream($stream, 'iconv', 'ISO-8859-1//TRANSLIT//IGNORE', 'UTF-8');
      
  7. PHP Stream Resource Lifecycle:

    • Issue: Wrapping PHP resources (e.g., fopen) in PSR-7 streams requires manual cleanup.
    • Fix: Use LazyOpenStream or ensure resources are closed:
      $stream = Utils::streamFor(fopen('file.txt', 'r'));
      // ... use stream ...
      fclose($stream->detach());
      

Debugging Tips

  1. Stream Inspection:

    • Dump stream metadata:
      var_dump($stream->getMetadata());
      
    • Check stream size/position:
      echo $stream->getSize(), ' | ', $stream->tell();
      
  2. Logging Stream Content:

    • Use Utils::copyToString() to inspect content:
      $content = Utils::copyToString($stream);
      \Log::debug('Stream content:', ['content' => $content]);
      
  3. Decorator Debugging:

    • Wrap streams in FnStream for debugging:
      $debugStream = FnStream::decorate($stream, [
          'read' => function ($length) use ($stream) {
              \Log::debug('Reading', ['length' => $length]);
              return $stream->read($length);
          },
      ]);
      
  4. Common Exceptions:

    • RuntimeException: Thrown for invalid operations (e.g., seeking on non-seekable streams).
    • InvalidArgumentException: Invalid input to utilities (e.g., Query::parse).
    • Fix: Validate inputs and streams before operations.

Extension Points

  1. Custom Stream Decorators:
    • Extend StreamDecoratorTrait for reusable decorators:
      class LoggingStream implements StreamInterface {
          use StreamDecoratorTrait;
      
          public function
      
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