fix: resolve RedisCache array offset error and improve discovery diagnostics

- Fix RedisCache driver to handle MGET failures gracefully with fallback
- Add comprehensive discovery context comparison debug tools
- Identify root cause: WEB context discovery missing 166 items vs CLI
- WEB context missing RequestFactory class entirely (52 vs 69 commands)
- Improved exception handling with detailed binding diagnostics
This commit is contained in:
2025-09-12 20:05:18 +02:00
parent 8040d3e7a5
commit e30753ba0e
46990 changed files with 10789682 additions and 89639 deletions

View File

@@ -13,6 +13,7 @@ use Fiber;
*/
final class AsyncHttpClient
{
/** @var array<string, mixed> */
private array $defaultOptions = [
'timeout' => 30,
'connect_timeout' => 10,
@@ -23,6 +24,7 @@ final class AsyncHttpClient
public function __construct(
private readonly FiberManager $fiberManager = new FiberManager(),
/** @var array<string, mixed> */
array $defaultOptions = []
) {
$this->defaultOptions = array_merge($this->defaultOptions, $defaultOptions);
@@ -31,7 +33,7 @@ final class AsyncHttpClient
/**
* Sendet einen GET-Request
*/
public function get(string $url, array $headers = [], array $options = []): HttpResponse
public function get(string $url, /** @var array<string, string> */ array $headers = [], /** @var array<string, mixed> */ array $options = []): HttpResponse
{
return $this->request('GET', $url, null, $headers, $options);
}
@@ -39,7 +41,7 @@ final class AsyncHttpClient
/**
* Sendet einen POST-Request
*/
public function post(string $url, mixed $data = null, array $headers = [], array $options = []): HttpResponse
public function post(string $url, mixed $data = null, /** @var array<string, string> */ array $headers = [], /** @var array<string, mixed> */ array $options = []): HttpResponse
{
return $this->request('POST', $url, $data, $headers, $options);
}
@@ -47,7 +49,7 @@ final class AsyncHttpClient
/**
* Sendet einen PUT-Request
*/
public function put(string $url, mixed $data = null, array $headers = [], array $options = []): HttpResponse
public function put(string $url, mixed $data = null, /** @var array<string, string> */ array $headers = [], /** @var array<string, mixed> */ array $options = []): HttpResponse
{
return $this->request('PUT', $url, $data, $headers, $options);
}
@@ -55,7 +57,7 @@ final class AsyncHttpClient
/**
* Sendet einen DELETE-Request
*/
public function delete(string $url, array $headers = [], array $options = []): HttpResponse
public function delete(string $url, /** @var array<string, string> */ array $headers = [], /** @var array<string, mixed> */ array $options = []): HttpResponse
{
return $this->request('DELETE', $url, null, $headers, $options);
}
@@ -63,11 +65,12 @@ final class AsyncHttpClient
/**
* Sendet mehrere Requests parallel
*
* @param array<string, array> $requests ['key' => ['method' => 'GET', 'url' => '...', ...]]
* @param array<string, array<string, mixed>> $requests ['key' => ['method' => 'GET', 'url' => '...', ...]]
* @return array<string, HttpResponse>
*/
public function requestMultiple(array $requests): array
{
/** @var array<string, \Closure> */
$operations = [];
foreach ($requests as $key => $request) {
$operations[$key] = fn () => $this->request(
@@ -84,6 +87,9 @@ final class AsyncHttpClient
/**
* Sendet Requests mit begrenzter Parallelität
*
* @param array<string, array<string, mixed>> $requests
* @return array<string, HttpResponse>
*/
public function requestBatch(array $requests, int $maxConcurrency = 10): array
{
@@ -108,7 +114,7 @@ final class AsyncHttpClient
/**
* Hauptmethode für HTTP-Requests
*/
private function request(string $method, string $url, mixed $data = null, array $headers = [], array $options = []): HttpResponse
private function request(string $method, string $url, mixed $data = null, /** @var array<string, string> */ array $headers = [], /** @var array<string, mixed> */ array $options = []): HttpResponse
{
$options = array_merge($this->defaultOptions, $options);
@@ -143,8 +149,9 @@ final class AsyncHttpClient
/**
* @return resource
*/
private function createContext(string $method, mixed $data, array $headers, array $options)
private function createContext(string $method, mixed $data, /** @var array<string, string> */ array $headers, /** @var array<string, mixed> */ array $options)
{
/** @var array<string, array<string, mixed>> */
$contextOptions = [
'http' => [
'method' => $method,
@@ -166,6 +173,7 @@ final class AsyncHttpClient
}
if (! empty($headers)) {
/** @var array<int, string> */
$headerStrings = [];
foreach ($headers as $key => $value) {
$headerStrings[] = "$key: $value";
@@ -176,8 +184,13 @@ final class AsyncHttpClient
return stream_context_create($contextOptions);
}
/**
* @param array<int, string> $httpResponseHeader
* @return array<string, string>
*/
private function parseHeaders(array $httpResponseHeader): array
{
/** @var array<string, string> */
$headers = [];
foreach ($httpResponseHeader as $header) {
if (strpos($header, ':') !== false) {
@@ -189,6 +202,9 @@ final class AsyncHttpClient
return $headers;
}
/**
* @param array<int, string> $httpResponseHeader
*/
private function extractStatusCode(array $httpResponseHeader): int
{
if (empty($httpResponseHeader)) {

View File

@@ -53,6 +53,8 @@ final readonly class HttpResponse
/**
* Konvertiert zu Array
*
* @return array<string, mixed>
*/
public function toArray(): array
{