Skip to content

Commit e256fb6

Browse files
Merge pull request #6 from InitPHP/3.x
3.x
2 parents f8f07bf + 3a56e45 commit e256fb6

89 files changed

Lines changed: 10082 additions & 3653 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_style = space
7+
indent_size = 4
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.{yml,yaml,json}]
15+
indent_size = 2
16+
17+
[Makefile]
18+
indent_style = tab
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Static Analysis
2+
3+
on:
4+
push:
5+
branches: [main, 2.x, 3.x]
6+
pull_request:
7+
branches: [main, 2.x, 3.x]
8+
9+
jobs:
10+
phpstan:
11+
name: PHPStan
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Setup PHP
19+
uses: shivammathur/setup-php@v2
20+
with:
21+
php-version: '8.2'
22+
extensions: json, curl, mbstring
23+
coverage: none
24+
tools: composer:v2
25+
26+
- name: Install dependencies
27+
run: composer update --no-interaction --no-progress --prefer-dist
28+
29+
- name: Run PHPStan
30+
run: vendor/bin/phpstan analyse --no-progress --memory-limit=512M

.github/workflows/tests.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main, 2.x, 3.x]
6+
pull_request:
7+
branches: [main, 2.x, 3.x]
8+
9+
jobs:
10+
phpunit:
11+
name: PHPUnit (PHP ${{ matrix.php }} / ${{ matrix.dependency-version }})
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
17+
dependency-version: [prefer-stable]
18+
include:
19+
- php: '7.4'
20+
dependency-version: prefer-lowest
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Setup PHP
27+
uses: shivammathur/setup-php@v2
28+
with:
29+
php-version: ${{ matrix.php }}
30+
extensions: json, curl, mbstring
31+
coverage: none
32+
tools: composer:v2
33+
34+
# Composer's solver picks PHPUnit 9.x and http-factory-tests 1.x on
35+
# PHP < 8.1, and 10.x / 2.x on PHP >= 8.1, based on the wide ranges in
36+
# composer.json. No manual narrowing required.
37+
- name: Install dependencies
38+
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress --prefer-dist
39+
40+
- name: Run PHPUnit
41+
run: vendor/bin/phpunit --testdox

CHANGELOG.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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

Comments
 (0)