Guzzle PSR-7 2.0 is a major release that removes deprecated APIs, raises the minimum PHP version, and adds PHP 7 parameter and return types. Applications that only depend on PSR-7 interfaces should usually need small changes. Applications that call helper functions, extend package classes, or pass invalid argument types need closer review.
Guzzle PSR-7 2.0 requires PHP ^7.2.5 || ^8.0. Guzzle PSR-7 1.x supported PHP
>=5.4.0.
Composer dependency changes that can affect upgrades:
ralouphie/getallheadersv2 support was dropped; 2.0 requires^3.0.psr/http-factory:^1.0is required because 2.0 ships PSR-17 factories throughGuzzleHttp\Psr7\HttpFactory.
Type hints and return types were added wherever possible. Please make sure:
- You pass values of the documented type when calling methods and functions.
- Classes that extend Guzzle PSR-7 classes update any overridden method signatures to remain compatible.
- Code that expected package-specific
InvalidArgumentExceptionexceptions for invalid argument types may now receive PHPTypeErrorexceptions instead.
Common examples include passing a real integer status code to Response::__construct() and passing a string method to Request::__construct().
The static API was introduced in 1.7.0 to mitigate problems with functions
conflicting between global and local copies of the package. The function API was
removed in 2.0.0, along with the Composer files autoload entry that loaded
src/functions_include.php.
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');| Original Function | Replacement Method |
|---|---|
str |
Message::toString |
uri_for |
Utils::uriFor |
stream_for |
Utils::streamFor |
parse_header |
Header::parse |
normalize_header |
Header::normalize |
modify_request |
Utils::modifyRequest |
rewind_body |
Message::rewindBody |
try_fopen |
Utils::tryFopen |
copy_to_string |
Utils::copyToString |
copy_to_stream |
Utils::copyToStream |
hash |
Utils::hash |
readline |
Utils::readLine |
parse_request |
Message::parseRequest |
parse_response |
Message::parseResponse |
parse_query |
Query::parse |
build_query |
Query::build |
mimetype_from_filename |
MimeType::fromFilename |
mimetype_from_extension |
MimeType::fromExtension |
_parse_message |
Message::parseMessage |
_parse_request_uri |
Message::parseRequestUri |
get_message_body_summary |
Message::bodySummary |
_caseless_remove |
Utils::caselessRemove |
Header::normalize() remains the direct 2.0 replacement for
normalize_header(). In newer 2.x versions, prefer Header::splitList() for
new code.
The deprecated Uri::resolve() and Uri::removeDotSegments() methods were
removed. 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');Guzzle PSR-7 1.x automatically fixed a URI that combined an authority with a
relative path by prepending / to the path. That deprecated behavior was removed
in 2.0. Such URIs now throw InvalidArgumentException.
// Before: automatically converted to //example.com/foo.
$uri = (new Uri())->withHost('example.com')->withPath('foo');
// After: make the absolute path explicit.
$uri = (new Uri())->withHost('example.com')->withPath('/foo');Header names are validated more strictly according to RFC 7230 token syntax.
Names containing whitespace, /, (, ), \\, or other invalid characters are
rejected.
If you construct messages from untrusted or non-standard input, normalize or
reject invalid header names before constructing Request, Response, or
ServerRequest instances.
Query::build() now serializes booleans as 1 and 0, matching
http_build_query() behavior.
Query::build(['enabled' => true, 'disabled' => false]);
// enabled=1&disabled=0In current 2.x versions, pass false as the third argument if you need textual
boolean values:
Query::build(['enabled' => true, 'disabled' => false], PHP_QUERY_RFC3986, false);
// enabled=true&disabled=falseSeveral classes that were annotated with @final in 1.x are declared final in
2.0:
AppendStreamBufferStreamCachingStreamDroppingStreamFnStreamInflateStreamLazyOpenStreamLimitStreamMultipartStreamNoSeekStreamPumpStreamStreamWrapper
If your code extends one of these classes, replace inheritance with composition.
For custom streams, implement Psr\Http\Message\StreamInterface directly or use
GuzzleHttp\Psr7\StreamDecoratorTrait in your own class.
Request, Response, ServerRequest, Stream, UploadedFile, and Uri remain
extendable in 2.0, but overridden methods must have compatible signatures.
Some constants that were public in 1.x are implementation details in 2.0:
Stream::READABLE_MODESStream::WRITABLE_MODESUri::HTTP_DEFAULT_HOST
If your code used these constants, define application-specific constants instead of depending on package internals.
BufferStream::write() returns 0 instead of false when the buffer exceeds
its high-water mark. This keeps the method compatible with the int return type
from StreamInterface::write().
Several stream __toString() implementations now catch Throwable. On PHP 7.4
and newer, exceptions thrown during stringification are rethrown. Avoid relying
on (string) $stream to hide read failures; call getContents() or read() and
handle exceptions when failures are possible.
Guzzle PSR-7 2.0 adds GuzzleHttp\Psr7\HttpFactory, an implementation of the
PSR-17 factory interfaces from psr/http-factory. This is additive, but it is
the reason for the new required dependency.
For the full 2.0 diff, see https://github.com/guzzle/psr7/compare/1.8.1...2.0.0.