199 lines
6.6 KiB
Markdown
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.
|