Как можно автоматизировать повторный запрос с изменением одного параметра, когда получены ошибочные HTTP-статусы с библиотеку Guzzle в PHP?
Для изменения GET параметров в Guzzle middleware можно использовать метод "setQuery" объекта Request. Пример кода:
```php
use GuzzleHttp\Client;
$client = new Client();
// создаем объект запроса
$request = $client->get('http://example.com', [
'query' => ['param1' => 'value1']
]);
// изменяем GET параметры
$newParams = ['param2' => 'value2'];
$request = $request->setQuery($newParams);
// отправляем запрос
$response = $client->send($request);
```
Для автоматизации повторного запроса с изменением одного параметра при получении ошибочных HTTP-статусов, можно использовать middleware Guzzle. Пример кода:
```php
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\ResponseInterface;
$client = new Client();
$handler = HandlerStack::create();
$errorHandler = function (callable $handler) {
return function ($request, array $options) use ($handler) {
return $handler($request, $options)->then(function (ResponseInterface $response) use ($handler) {
if ($response->getStatusCode() >= 400) {
$uri = $request->getUri();
$query = $uri->getQuery();
$newParams = ['param2' => 'value2'];
$newRequest = $request->withUri($uri->withQuery(http_build_query($newParams)));
return $handler($newRequest, $options);
}
return $response;
});
};
};
$handler->push(Middleware::mapRequest($errorHandler));
$client = new Client(['handler' => $handler]);
$response = $client->get('http://example.com');
```
Этот код добавляет middleware, которое будет перехватывать ответы с ошибочными HTTP-статусами и менять один из GET параметров перед повторной отправкой запроса.
C чистым <code>Middleware::retry</code> вы не решите задачу. Но можете скопировать класс <code>GuzzleHttp\RetryMiddleware</code> к себе в проект и подправить метод doRetry: <br/> <br/> <pre><code class="php">private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface
{
$options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
$uri = $request->getUri();
$query = $uri->getQuery();
// делаете какие нужно изменения в query
$request = $request->withUri($uri->withQuery($query));
return $this($request, $options);
}</code></pre> <br/> <br/> А дальше добавляете в стек: <br/> <br/> <pre><code class="php">public function addRetryMiddleware($maxRetries)
{
$retryMiddleware = fn($handler) => new MyCustomRetryMiddleware(
function (
$retries,
RequestInterface $request,
ResponseInterface $response = null,
TransferException $exception = null
) use ($maxRetries) {
if ($retries >= $maxRetries) {
return false;
}
if ($exception instanceof TransferException || ($response && $response->getStatusCode() >= 500)) {
return true;
}
return false;
},
$handler,
function ($retries) {
return $retries * 1000;
}
);
$this->handlerStack->push($retryMiddleware);
}</code></pre>