Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ The format is based on Keep a Changelog.

### Changed
- Refactored `HttpClient` internals behind explicit `CurlAdapter` and `MultiCurlAdapter` wrappers while preserving the existing facade methods and keeping `php-curl-class` as the underlying transport for this phase (#534)
- Replaced the single-request `HttpClient` `CurlAdapter` execution path with native PHP cURL while keeping the multi-curl adapter and `php-curl-class` dependency in place until the multi-request migration is complete (#566)
- Replaced the single-request `HttpClient` `CurlAdapter` execution path with native PHP cURL (#566)
- Replaced the multi-request `HttpClient` `MultiCurlAdapter` execution path with native PHP multi-curl and removed the `php-curl-class` dependency while preserving facade, factory, helper, callback, and response aggregation behavior (#567)
- Refactored the Lang package to resolve adapter instances through `LangFactory` configuration and load file translations lazily on first use instead of preloading them during web boot (#533)
- **BREAKING:** Reshaped Lang configuration so `lang.default` now selects the adapter, locale fallback moved to `lang.default_locale`, and the unused `lang.enabled` toggle was removed (#533)
- **BREAKING:** Removed `Lang::isEnabled()` from the public Lang API because it no longer affected runtime behavior (#533)
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"dflydev/dot-access-data": "^3.0",
"php-debugbar/php-debugbar": "^2.2",
"phpmailer/phpmailer": "^7.1",
"php-curl-class/php-curl-class": "^13.0",
"psr/log": "^2.0",
"rakibtg/sleekdb": "^2.13",
"swagger-api/swagger-ui": "^5.32",
Expand Down
78 changes: 25 additions & 53 deletions src/HttpClient/Adapters/CurlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
namespace Quantum\HttpClient\Adapters;

use Quantum\HttpClient\Contracts\CurlAdapterInterface;
use Quantum\HttpClient\Traits\AdapterTrait;
use Quantum\HttpClient\ResponseHeaders;
use JsonSerializable;
use RuntimeException;
use CurlHandle;
use Curl\Curl;
use CURLFile;

/**
Expand All @@ -24,9 +24,11 @@
*/
class CurlAdapter implements CurlAdapterInterface
{
private static int $lastId = 0;
use AdapterTrait;

private const SUPPORTED_METHODS = ['setHeader', 'setHeaders', 'setOpt', 'setOpts'];

private ?Curl $client;
private static int $lastId = 0;

private CurlHandle $handle;

Expand Down Expand Up @@ -59,12 +61,8 @@ class CurlAdapter implements CurlAdapterInterface

private ?string $errorMessage = null;

/**
* The injected vendor client is a temporary bridge for MultiCurlAdapter until #567.
*/
public function __construct(?Curl $client = null)
public function __construct()
{
$this->client = $client;
$this->id = self::$lastId++;

$handle = curl_init();
Expand Down Expand Up @@ -102,7 +100,6 @@ public function setUrl(string $url): CurlAdapterInterface
{
$this->url = $url;
$this->applyOption(CURLOPT_URL, $url);
$this->client?->setUrl($url);

return $this;
}
Expand All @@ -113,7 +110,6 @@ public function setUrl(string $url): CurlAdapterInterface
public function setOpt(int $option, $value): CurlAdapterInterface
{
$this->applyOption($option, $value);
$this->client?->setOpt($option, $value);

return $this;
}
Expand All @@ -137,7 +133,6 @@ public function setHeader(string $key, $value): CurlAdapterInterface
{
$this->headers[$key] = $value;
$this->applyHeaders();
$this->client?->setHeader($key, $value);

return $this;
}
Expand All @@ -152,7 +147,6 @@ public function setHeaders(array $headers): CurlAdapterInterface
}

$this->applyHeaders();
$this->client?->setHeaders($headers);

return $this;
}
Expand All @@ -163,10 +157,6 @@ public function setHeaders(array $headers): CurlAdapterInterface
*/
public function buildPostData($data)
{
if ($this->client !== null) {
return $this->client->buildPostData($data);
}

if (
$this->hasJsonContentType() &&
(
Expand Down Expand Up @@ -239,14 +229,18 @@ private function hasCurlFile(array $data): bool

public function start(): void
{
if ($this->client !== null) {
$this->client->exec();
return;
}

$this->resetResponseState();

$rawResponse = curl_exec($this->handle);

$this->finalizeResponse($rawResponse);
}

/**
* @param mixed $rawResponse
*/
public function finalizeResponse($rawResponse): void
{
$curlErrorCode = curl_errno($this->handle);
$curlErrorMessage = curl_error($this->handle);
$httpStatusCode = (int) $this->getInfo(CURLINFO_HTTP_CODE);
Expand All @@ -270,86 +264,64 @@ public function start(): void
*/
public function getId()
{
return $this->client !== null ? $this->client->getId() : $this->id;
return $this->id;
}

public function isError(): bool
{
return $this->client !== null ? $this->client->isError() : $this->error;
return $this->error;
}

public function getErrorCode(): int
{
return $this->client !== null ? $this->client->getErrorCode() : $this->errorCode;
return $this->errorCode;
}

public function getErrorMessage(): ?string
{
return $this->client !== null ? $this->client->getErrorMessage() : $this->errorMessage;
return $this->errorMessage;
}

/**
* @return iterable<string, mixed>
*/
public function getResponseHeaders(): iterable
{
return $this->client !== null ? $this->client->getResponseHeaders() : $this->responseHeaders;
return $this->responseHeaders;
}

/**
* @return mixed
*/
public function getResponseCookies()
{
return $this->client !== null ? $this->client->getResponseCookies() : $this->responseCookies;
return $this->responseCookies;
}

/**
* @return mixed
*/
public function getResponse()
{
return $this->client !== null ? $this->client->getResponse() : $this->response;
return $this->response;
}

/**
* @return mixed
*/
public function getInfo(?int $option = null)
{
if ($this->client !== null) {
return $option !== null ? $this->client->getInfo($option) : $this->client->getInfo();
}

return $option !== null ? curl_getinfo($this->handle, $option) : curl_getinfo($this->handle);
}

public function getUrl(): ?string
{
return $this->url ?? $this->client?->getUrl();
return $this->url;
}

public function supportsMethod(string $method): bool
public function getHandle(): CurlHandle
{
return in_array($method, ['setHeader', 'setHeaders', 'setOpt', 'setOpts'], true)
|| ($this->client !== null && method_exists($this->client, $method));
}

/**
* @param array<mixed> $arguments
* @return mixed
*/
public function callMethod(string $method, array $arguments)
{
if (in_array($method, ['setHeader', 'setHeaders', 'setOpt', 'setOpts'], true)) {
return $this->$method(...$arguments);
}

if ($this->client === null) {
return null;
}

return $this->client->$method(...$arguments);
return $this->handle;
}

private function resetResponseState(): void
Expand Down
Loading
Loading