2026-05-24 00:20:06 +00:00

199 lines
6.6 KiB
Markdown

Guzzle PSR-7 Upgrade Guide
==========================
1.x to 2.0
----------
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.
#### PHP Version and Dependencies
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/getallheaders` v2 support was dropped; 2.0 requires `^3.0`.
- `psr/http-factory:^1.0` is required because 2.0 ships PSR-17 factories through `GuzzleHttp\Psr7\HttpFactory`.
#### PHP 7 Type Hints and Return Types
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 `InvalidArgumentException` exceptions for invalid argument types may now receive PHP `TypeError` exceptions instead.
Common examples include passing a real integer status code to `Response::__construct()` and passing a string method to `Request::__construct()`.
#### Removed Function API
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:
```php
// 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.
#### Deprecated URI Methods Removed
The deprecated `Uri::resolve()` and `Uri::removeDotSegments()` methods were
removed. Use `UriResolver` instead.
```php
// 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');
```
#### Stricter URI Validation
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`.
```php
// 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 Validation
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 String Boolean Serialization
`Query::build()` now serializes booleans as `1` and `0`, matching
`http_build_query()` behavior.
```php
Query::build(['enabled' => true, 'disabled' => false]);
// enabled=1&disabled=0
```
In current 2.x versions, pass `false` as the third argument if you need textual
boolean values:
```php
Query::build(['enabled' => true, 'disabled' => false], PHP_QUERY_RFC3986, false);
// enabled=true&disabled=false
```
#### Final Stream and Decorator Classes
Several classes that were annotated with `@final` in 1.x are declared `final` in
2.0:
- `AppendStream`
- `BufferStream`
- `CachingStream`
- `DroppingStream`
- `FnStream`
- `InflateStream`
- `LazyOpenStream`
- `LimitStream`
- `MultipartStream`
- `NoSeekStream`
- `PumpStream`
- `StreamWrapper`
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.
#### Public Constants and Internal Details
Some constants that were public in 1.x are implementation details in 2.0:
- `Stream::READABLE_MODES`
- `Stream::WRITABLE_MODES`
- `Uri::HTTP_DEFAULT_HOST`
If your code used these constants, define application-specific constants instead
of depending on package internals.
#### Stream Behavior Changes
`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.
#### PSR-17 Factories
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.