Repository navigation
Description
Follow-up to #534. The adapter extraction introduced CurlAdapter and MultiCurlAdapter, but the public creation/lifecycle model is still unclear.
Current issues:
HttpClientFactory::get()returns a cached mutableHttpClient.HttpClientstores request-specific state: method, data, request headers, responses, and errors.- Reusing a cached
HttpClientcan leak state between requests unless everycreate*Request()call resets state. HttpClientTypeexists but is not currently used.HttpClientdirectly constructsCurlAdapter/MultiCurlAdapter.- Public usage is unclear:
new HttpClient(),HttpClientFactory::get(), and future helper usage are not aligned. - Core packages currently instantiate or inject
HttpClientdirectly and callcreateRequest(), so removing those methods immediately is not safe.
Goal
Define and implement a coherent request-context creation model for HttpClient, while preserving backward compatibility with existing consumers.
Proposed Direction
Treat HTTP requests as fresh request contexts, closer to PaginatorFactory::create(...) than cached service factories like Cache/Mailer.
Add factory methods that return fresh configured clients:
HttpClientFactory::createRequest(string $url, ?Curl $client = null): HttpClient
HttpClientFactory::createMultiRequest(?MultiCurl $client = null): HttpClient
HttpClientFactory::createAsyncMultiRequest(callable $success, callable $error, ?MultiCurl $client = null): HttpClientAdd helper functions:
httpRequest(string $url, ?Curl $client = null): HttpClient
httpMultiRequest(?MultiCurl $client = null): HttpClient
httpAsyncMultiRequest(callable $success, callable $error, ?MultiCurl $client = null): HttpClientKeep existing instance methods for compatibility:
HttpClient::createRequest()
HttpClient::createMultiRequest()
HttpClient::createAsyncMultiRequest()Do not promote cached HttpClientFactory::get() for request usage. Either remove it if safe, or deprecate it if it may already be used externally.
Tasks
- Audit current core usages of
HttpClient. - Add fresh request-context factory methods.
- Add helper functions for single, multi, and async multi requests.
- Decide whether
HttpClientFactory::get()should be removed or deprecated. - Decide whether
HttpClientTypeshould be removed or used internally. - Keep backward-compatible
HttpClient::create*Request()methods unless a breaking change is explicitly accepted. - Add tests proving each factory/helper call returns a fresh request context.
- Add tests for no stale state between sequential requests.
- Update core package usages where appropriate:
- Captcha
- Lang
- Storage
- Mailer
- Update documentation/changelog with recommended usage.
Acceptance Criteria
httpRequest($url)creates a fresh single-requestHttpClient.httpMultiRequest()creates a fresh multi-requestHttpClient.httpAsyncMultiRequest($success, $error)creates a fresh async multi-requestHttpClient.- Factory request-creation methods return fresh instances.
- No request state leaks between factory/helper-created requests.
- Existing direct usage with
new HttpClient()->createRequest()still works. - Existing core package tests pass.
- Downstream
save_remote_image()works using the new helper/factory style. HttpClientTypeis either used meaningfully or removed.HttpClientFactory::get()is removed or clearly deprecated to avoid cached mutable-request misuse.
Validation
Run:
vendor/bin/phpunit tests/Unit/HttpClient
vendor/bin/phpunit tests/Unit/Captcha tests/Unit/Lang tests/Unit/Storage tests/Unit/Mailer
composer cs:check
composer phpstanAlso perform downstream smoke test in quantum-php-project:
- point
quantum/frameworkto local core path repository; - update
save_remote_image()to use the new helper/factory style; - verify a real HTTP image download saves the expected file body.
Activity
armanist commentedon Jul 18, 2026
Updated implementation direction after design review:
HttpClientFactory::get()should be removed.HttpClientFactoryshould expose only fresh request-context creation methods:Curl/MultiCurlparameters. Vendor injection remains only on the existingHttpClient::create*Request()compatibility methods for tests/internal compatibility.HttpClient::createRequest(),HttpClient::createMultiRequest(), andHttpClient::createAsyncMultiRequest()for backward compatibility.HttpClientType; no genericcreate(string $type, array $params)API is planned for this ticket.resetRequestState()in this ticket because the new factory/helper APIs return freshHttpClientinstances and the existing instance methods are kept only for compatibility.This narrows the ticket to a fresh request-context factory/helper API and avoids exposing vendor classes through the new public helper/factory surface.
[#563] Refactor HttpClient request factory
[#563] Remove unused HttpClient type enum
[#563] Add HttpClient request helpers
[#563] Update HttpClient factory helper tests
[#563] Align HttpClient adapter start contract