|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to **initphp/http** will be documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), |
| 6 | +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | + |
| 8 | +## [3.0.0] - Unreleased |
| 9 | + |
| 10 | +### Added |
| 11 | + |
| 12 | +- **PSR-7 v2 support.** `psr/http-message` constraint widened to `^1.0 || ^2.0`. |
| 13 | +- **Stateless `ServerRequest::createFromGlobals()`** that accepts optional `$server/$get/$post/$cookies/$files` arrays and never caches its result. Safe under Swoole, RoadRunner, Octane, FrankenPHP. |
| 14 | +- **Content-Type-aware body parsing** in `createFromGlobals` (JSON / urlencoded / multipart). |
| 15 | +- **nginx + php-fpm header fallback** in `createFromGlobals` for environments without `apache_request_headers()`. |
| 16 | +- **`Client::withTimeout()` / `withConnectTimeout()` / `withFollowRedirects()` / `withCurlOptions()`** for production-grade configuration. |
| 17 | +- **`Facadable` trait and `FacadableInterface`** — canonical names replacing the misspelled `Facadeble[Interface]` (old names kept as `@deprecated` aliases). |
| 18 | +- **`docs/` directory** with PSR-7/17/18 guides, emitter walk-throughs, recipes, status-code reference and an upgrade guide. |
| 19 | +- **Comprehensive `tests/Unit/` suite** complementing the upstream PSR integration tests. |
| 20 | +- **GitHub Actions CI** matrix covering PHP 7.4 – 8.4 (PHPUnit + PHPStan). |
| 21 | +- **PHPStan level 5** static analysis with a baseline of intentional ignores. |
| 22 | +- Packagist metadata enrichment (description, keywords, homepage, support links). |
| 23 | +- Composer scripts: `composer test`, `composer test:coverage`, `composer phpstan`, `composer ci`. |
| 24 | +- EditorConfig, CHANGELOG, contributor-friendly docblocks across `src/`. |
| 25 | +- `http-interop/http-factory-tests` dev-dep widened to `^1.1 || ^2.0` so the CI matrix can install the v1 line on PHP 7.4 / 8.0 (the v2 line requires PHP 8.1+). |
| 26 | + |
| 27 | +### Changed (breaking) |
| 28 | + |
| 29 | +- **`Request::createFromGlobals()` removed.** Use `ServerRequest::createFromGlobals()`. |
| 30 | +- **`Request::_parameters` bag removed.** All of `__get/__set/__isset/all/get/has/merge/sendRequest` are gone. Use `getParsedBody()` / attributes / explicit `(new Client())->sendRequest($request)`. |
| 31 | +- **Custom `InitPHP\HTTP\Message\Interfaces\*` interfaces removed.** Type-hint against `Psr\Http\Message\*Interface` directly. The old interfaces forced mutator contracts that conflicted with PSR-7 immutability. |
| 32 | +- **`Client::sendRequest()`** no longer special-cases the concrete `Request` class or silently JSON-encodes a `_parameters` bag. |
| 33 | +- **`Client::prepareRequest()`** (used by the verb helpers and `fetch()`) no longer accepts `array`, `DOMDocument`, `SimpleXMLElement`, or "any object". Body must be `string | resource | StreamInterface | null`. The `send_request()` helper still encodes arrays/`toArray()` objects as JSON. |
| 34 | +- **`Client` default timeout** changed from 0 (no timeout) to 30 s; default connect timeout 10 s. Pass `->withTimeout(0)` to keep the legacy infinite wait. |
| 35 | +- **`Response::redirect()`** always sets `Location`; `Refresh` is added on top when a non-zero delay is requested. |
| 36 | +- **`Response::json()`** uses `JSON_THROW_ON_ERROR`; unencodable payloads now raise `InvalidArgumentException` instead of silently producing `false`. Content-Type is `application/json; charset=utf-8`. |
| 37 | +- **`UploadedFile::__construct()` `$size` is now `?int`**, matching the PSR-7 nullable contract. |
| 38 | +- **`UploadedFile::getSize(): ?int`**, matching the PSR-7 contract. |
| 39 | +- **`Stream::__toString()` no longer throws** under any circumstance, per PSR-7's hard requirement. |
| 40 | +- **`Stream::write()` string backend** now obeys `fwrite()` semantics (overwrite from cursor, advance position). The legacy prepend-at-position-0 behaviour is gone. |
| 41 | +- **`Stream::str2resorce()` renamed** to `Stream::stringToResource()` (private). Materialised detach handle now preserves cursor position. |
| 42 | +- **`RequestTrait::updateHostFormUri()` renamed** to `updateHostFromUri()`. |
| 43 | +- **HTTP version whitelist widened** to accept `2`, `2.0`, `3`, `3.0` (alongside `1.0` and `1.1`). |
| 44 | +- **Native return types added for PSR-7 v2 covariance** on seven methods: |
| 45 | + `Stream::close(): void`, `Stream::seek(...): void`, `Stream::rewind(): void`, |
| 46 | + `MessageTrait::getHeader($name): array`, |
| 47 | + `UploadedFile::getStream(): StreamInterface`, `UploadedFile::moveTo(...): void`, |
| 48 | + `Uri::__toString(): string`. |
| 49 | + Required by PHP 7.4 + PSR-7 v2 (`Declaration must be compatible with ...` |
| 50 | + fatal at class load); PHP 8.0+ accepted the untyped signatures silently |
| 51 | + but the fix is uniform across all supported PHP versions. |
| 52 | + No call-site change is required (the existing `@return` PHPDoc lines |
| 53 | + already documented these types), but subclass overrides must match the |
| 54 | + new signatures or stay untyped. |
| 55 | + |
| 56 | +### Fixed |
| 57 | + |
| 58 | +- 500 reason phrase corrected from `'Internal ServerRequest Error'` to `'Internal Server Error'`. |
| 59 | +- `Stream::isEmpty()` / `isNotEmpty()` return `false` for streams whose size is null (pipes, sockets), instead of mis-classifying them as empty. |
| 60 | +- `Emitter` reason-phrase status-line check uses `!== ''` so a literal `'0'` reason is preserved. |
| 61 | +- `Emitter` raises `EmitHeaderException` (not `EmitBodyException`) when `headers_sent()` is true. |
| 62 | +- `Client` sets `CURLOPT_POSTFIELDS` for body-bearing methods (POST/PUT/PATCH/DELETE) even when the body is empty, so cURL doesn't silently downgrade the request. |
| 63 | +- `Client::sendRequest()` wraps the response body in `php://temp` instead of an in-memory PHP string, avoiding OOM on multi-megabyte downloads. |
| 64 | +- `UploadedFile::moveTo()` survives partial-write iterations and retries until the chunk is flushed. |
| 65 | +- `ServerRequest::normalizeFiles()` recurses into arbitrarily nested file input names (`file[parent][child][…]`). |
| 66 | +- `send_request()` (global helper) requires a URL when the first arg is a method string instead of silently sending to `null`. |
| 67 | +- `tests/Unit/FixtureServerTrait` exposes the loopback host through a static method instead of a trait constant, so the unit suite loads on PHP 7.4 / 8.0 / 8.1 (trait constants are a PHP 8.2+ feature). |
| 68 | +- `static-analysis.yml` workflow now runs PHPStan with `--memory-limit=512M`, matching the `composer phpstan` script — the default 128 MiB triggered an OOM under PHP 7.4 during local reproduction. |
| 69 | + |
| 70 | +### Removed (in addition to breaking changes above) |
| 71 | + |
| 72 | +- `Request::__set/__get/__isset/all/get/has/merge/sendRequest/createFromGlobals` and the static singleton property that backed `createFromGlobals`. |
| 73 | +- `Client::sendRequest`'s `instanceof Request` branch. |
| 74 | +- `Client::prepareRequest`'s `DOMDocument`/`SimpleXMLElement`/`toArray()`/`get_object_vars()` cascade. |
| 75 | +- `src/Message/Interfaces/` directory (six custom interfaces). |
| 76 | + |
| 77 | +### Deprecated |
| 78 | + |
| 79 | +- `InitPHP\HTTP\Facade\Interfaces\FacadebleInterface` (use `FacadableInterface`). |
| 80 | +- `InitPHP\HTTP\Facade\Traits\Facadeble` (use `Facadable`). |
| 81 | + |
| 82 | +Both will be removed in 4.0. |
| 83 | + |
| 84 | +## [2.x] - prior releases |
| 85 | + |
| 86 | +See Git history for entries prior to this changelog. |
0 commit comments