guzzlehttp/psr7

repository·3.0·Indexed 27 days ago

https://github.com/guzzle/psr7

A PHP implementation of the PSR-7 HTTP message standard providing core objects such as Request, Response, URI, Stream, and UploadedFile. It includes PSR-17 factory implementations via HttpFactory, utility helpers for header and query string manipulation, and tools for parsing raw HTTP messages. The library ensures immutable message objects and provides locale-independent ASCII string manipulation through the Utils class.

Tokens
19.3K
Snippets
61
Records
114
Agent score
93%

What's inside guzzlehttp/psr7

  1. Migrate from Guzzle PSR-7 1.x to 2.0: PHP Version and Dependencies

    3.0

    Guzzle PSR-7 2.0 requires PHP ^7.2.5 || ^8.0.

    Key dependency changes:

    • ralouphie/getallheaders v2 support is dropped; 2.0 requires ^3.0.
    • psr/http-factory:^1.0 is now required because 2.0 includes GuzzleHttp\ Psr7\\HttpFactory (a PSR-17 implementation).
  2. Install guzzlehttp/psr7 via Composer

    3.0

    To use this package for creating or inspecting PSR-7 messages (requests, responses, URIs, uploaded files, and streams), install it using Composer.

    composer require guzzlehttp/psr7
  3. Migrate from 2.x to 3.0: URI Reference Relativization

    3.0

    In version 3.0, UriResolver::relativize() has been updated to return a network-path reference (e.g., //example.com) when the target URI has the same authority as the base URI but an empty path that cannot be expressed as a path reference. This ensures a documented round-trip guarantee.

    $base = new Uri('http://example.com/a');
    $target = new Uri('http://example.com');
    
    // 2.x
    (string) UriResolver::relativize($base, $target); // ../
    // which resolved back to http://example.com/
    
    // 3.0
    (string) UriResolver::relativize($base, $target); // //example.com
  4. Migrate from 2.x to 3.0: MultipartStream Headers and Boundaries

    3.0

    Significant changes have been made to MultipartStream to align with RFC 7578:

    • Content-Length: Default Content-Length headers are no longer added to individual parts. If a non-standard peer requires them, you must pass them explicitly in the headers array.
    • Escaping: Content-Disposition name and filename parameters are now escaped (e.g., " becomes %22).
    • Custom Boundaries: Explicit boundaries are validated against RFC 2046. The string '0' is now treated as a literal custom boundary. To use a generated random boundary, pass null or omit the argument.

    Example: Providing explicit Content-Length

    $body = new MultipartStream([
        [
            'name' => 'foo',
            'contents' => 'bar',
            'headers' => ['Content-Length' => '3'],
        ],
    ]);
  5. Migrate from 2.x to 3.0: Iterator-backed Streams

    3.0

    When creating streams via Utils::streamFor() using an Iterator, note the following changes in 3.0:

    • EOF Signaling: Iterator exhaustion is now the only way to signal EOF. Yielding false, null, or an empty string '' will no longer stop the stream; these are treated as zero-length chunks and are skipped.
    • Validation: Utils::streamFor() validates yielded values. Non-finite floats, arrays, resources, and non-stringable objects will throw an UnexpectedValueException when the stream is read.

    Example Migration:

    // Before: yielding false or null could stop an iterator-backed stream early.
    $stream = Utils::streamFor(new ArrayIterator([false, 'body']));
    
    // After: false and null are skipped chunks. End the iterator to signal EOF.
    $stream = Utils::streamFor(new ArrayIterator(['body']));
  6. Update Uploaded Files and $_FILES Handling for Guzzle PSR-7 3.0

    3.0

    Guzzle PSR-7 3.0 enforces stricter validation for uploaded files.

    ServerRequest::withUploadedFiles()

    Every leaf in the nested upload tree must be an instance of UploadedFileInterface. Invalid trees are now rejected.

    $_FILES Specifications

    ServerRequest::normalizeFiles() and ServerRequest::fromGlobals() reject malformed $_FILES arrays.

    • Single-file specifications must contain non-null tmp_name, size, and error values.
    • size and error must be non-negative PHP integers. Numeric strings are no longer cast to integers.
    • For nested specifications, tmp_name, size, and error must be arrays, and every key in tmp_name must have a corresponding entry in size and error.

    Example of valid 3.0 $_FILES structure:

    $files = ['file' => ['tmp_name' => '/tmp/php123', 'size' => 123, 'error' => UPLOAD_ERR_OK]];
    // 2.x, no longer accepted in 3.0
    $files = ['file' => ['tmp_name' => '/tmp/php123', 'error' => '0']];
    
    // 3.0
    $files = ['file' => ['tmp_name' => '/tmp/php123', 'size' => 123, 'error' => UPLOAD_ERR_OK]];
  7. Migrate from Guzzle PSR-7 1.x to 2.0: Replace Removed Function API with Static Methods

    3.0

    The global function API was removed in 2.0.0. Replace namespaced function calls with the corresponding static methods in the GuzzleHttp\\Psr7 namespace.

    // Before:
    use function GuzzleHttp\\Psr7\\stream_for;
    $stream = stream_for('body');
    
    // After:
    use GuzzleHttp\\Psr7\\Utils;
    $stream = Utils::streamFor('body');
  8. Migrate from 2.x to 3.0: URI Userinfo Redaction

    3.0

    The Utils::redactUserInfo() method is now stricter. It redacts all non-empty userinfo, including cases where only a username is present. In 2.x, it only redacted the password portion.

    Example Comparison:

    use GuzzleHttp\
    Psr7\\Uri;
    use GuzzleHttp\\Psr7\\Utils;
    
    // 2.x: https://TOKEN@example.com
    // 3.0: https://***@example.com
    (string) Utils::redactUserInfo(new Uri('https://TOKEN@example.com'));
    
    // 2.x: https://user:***@example.com
    // 3.0: https://***@example.com
    (string) Utils::redactUserInfo(new Uri('https://user:pass@example.com'));
    use GuzzleHttp\Psr7\Uri;
    use GuzzleHttp\Psr7\Utils;
    
    // 2.x: https://TOKEN@example.com
    // 3.0: https://***@example.com
    (string) Utils::redactUserInfo(new Uri('https://TOKEN@example.com'));
    
    // 2.x: https://user:***@example.com
    // 3.0: https://***@example.com
    (string) Utils::redactUserInfo(new Uri('https://user:pass@example.com'));
  9. Migrate from 2.x to 3.0: IPv6 Canonicalization

    3.0

    In version 3.0, IPv6 hosts are canonicalized to their RFC 5952 form when a URI is constructed. This affects getHost(), getAuthority(), and (string) $uri. Leading zeros are suppressed, hexadecimal fields are lowercase, and the longest run of two or more zero fields is collapsed with ::.

    Applications that persist URI strings (e.g., as cache keys) will see these new canonical forms. However, UriComparator::isCrossOrigin() and UriNormalizer::isEquivalent() will still treat equivalent IPv6 spellings as the same.

    // 2.x preserved the spelling as given
    (string) new Uri('http://[0:0:0:0:0:0:0:1]/'); // http://[0:0:0:0:0:0:0:1]/
    
    // 3.0
    (string) new Uri('http://[0:0:0:0:0:0:0:1]/');          // http://[::1]/
    (string) new Uri('http://[::FFFF:7F00:1]/');            // http://[::ffff:127.0.0.1]/
    (string) new Uri('http://[2001:db8:3:4::192.0.2.33]/'); // http://[2001:db8:3:4::c000:221]/
  10. Migrate from 2.x to 3.0: PumpStream Source Callables

    3.0

    When using PumpStream, the source callable must now return a non-empty string to produce data.

    • To signal EOF: Return false or null.
    • To signal 'temporarily no data': Do not return an empty string '' (this now throws a RuntimeException). Instead, wait until data is available and return a non-empty string.
    • Avoid infinite loops: Returning an empty string no longer triggers a retry; it results in an error.
  11. Migrate from Guzzle PSR-7 1.x to 2.0: Handling Final Stream Classes

    3.0

    Several stream classes are now declared final in 2.0 and cannot be extended via inheritance:

    • AppendStream, BufferStream, CachingStream, DroppingStream, FnStream, InflateStream, LazyOpenStream, LimitStream, MultipartStream, NoSeekStream, PumpStream, StreamWrapper.

    Solution: Replace inheritance with composition. For custom streams, implement Psr\Http\Message\StreamInterface directly or use GuzzleHttp\Psr7\StreamDecoratorTrait in your own class.

  12. Migrate from Guzzle PSR-7 1.x to 2.0: Replace Deprecated URI Methods

    3.0

    The methods Uri::resolve() and Uri::removeDotSegments() were removed in 2.0. Use UriResolver instead.

    // Before:
    $resolved = Uri::resolve($base, '../path');
    $path = Uri::removeDotSegments('/a/../b');
    
    // After:
    use GuzzleHttp\\Psr7\\UriResolver;
    use GuzzleHttp\\Psr7\\Utils;
    
    $resolved = UriResolver::resolve($base, Utils::uriFor('../path'));
    $path = UriResolver::removeDotSegments('/a/../b');