Handlers and Middleware

Клиенты Guzzle используют обработчик и систему промежуточного ПО для отправки HTTP-запросов.

Handlers

Функция обработчика принимает Psr\Http\Message\RequestInterface и массив опций запроса и возвращает GuzzleHttp\Promise\PromiseInterface, который выполняется с Psr\Http\Message\ResponseInterface или отклоняется с исключением. исключением.

Вы можете предоставить клиенту пользовательский обработчик, используя опцию handler опции конструктора клиента. Важно понимать, что некоторые параметры запроса используемых Guzzle, требуют, чтобы определенные промежуточные модули обернули обработчик, используемый клиентом. Вы можете гарантировать, что обработчик, который вы предоставляете клиенту, использует промежуточные модули по умолчанию, обернув обработчик в файл GuzzleHttp\HandlerStack::create(callable $handler = null) статический метод.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;

$handler = new CurlHandler();
$stack = HandlerStack::create($handler); // Wrap w/ middleware
$client = new Client(['handler' => $stack]);

Метод create добавляет обработчики по умолчанию в HandlerStack. Когда HandlerStack будет разрешен, обработчики будут выполняться в следующем порядке:

  1. Отправка запроса:
  1. http_errors - Нет оп при отправке запроса. Код статуса ответа проверяется в процессе обработки ответа при возврате обещания ответа вверх по в стек.
  2. allow_redirects - Нет оп при отправке запроса. Следование перенаправлениям происходит, когда обещание ответа возвращается в стек.
  3. cookies - Добавляет cookies к запросам.
  4. prepare_body - Тело HTTP-запроса будет подготовлено (например, добавить заголовки по умолчанию, такие как Content-Length, Content-Type и т.д.).
  5. <отправить запрос с обработчиком>
  1. Ответ обработки:
  1. prepare_body - нет операции по обработке ответа.
  2. cookies - извлекает cookies ответа в банку с печеньем.
  3. allow_redirects - Следит за перенаправлениями.
  4. http_errors - выбрасывает исключения, когда код статуса ответа >= 400.

При отсутствии аргумента $handler, GuzzleHttp\HandlerStack::create() выберет наиболее подходящий обработчик, основываясь на расширениях, доступных на вашей системе.

Важно

Обработчик, предоставляемый клиенту, определяет, как применяются опции запроса и используются для каждого запроса, отправленного клиентом. Например, если вы не у вас нет промежуточного ПО cookie, связанного с клиентом, то установка параметра cookies опция запроса не будет иметь никакого эффекта на запрос.

Middleware

Middleware расширяет функциональность обработчиков, вызывая их в в процессе генерации ответов. Вспомогательное ПО реализуется как функция высшего порядка функция, которая имеет следующий вид.

use Psr\Http\Message\RequestInterface;

function my_middleware()
{
    return function (callable $handler) {
        return function (RequestInterface $request, array $options) use ($handler) {
            return $handler($request, $options);
        };
    };
}

Функции Middleware возвращают функцию, которая принимает следующий обработчик для вызова. Эта возвращенная функция затем возвращает другую функцию, которая действует как составленный обработчик - она принимает запрос и параметры и возвращает обещание, которое выполняется с ответом. Ваше составленное промежуточное ПО может изменять запрос, добавлять пользовательские опции запроса и изменять обещание, возвращаемое последующим обработчиком.

Вот пример добавления заголовка к каждому запросу.

use Psr\Http\Message\RequestInterface;

function add_header($header, $value)
{
    return function (callable $handler) use ($header, $value) {
        return function (
            RequestInterface $request,
            array $options
        ) use ($handler, $header, $value) {
            $request = $request->withHeader($header, $value);
            return $handler($request, $options);
        };
    };
}

После создания промежуточного ПО вы можете добавить его к клиенту, либо обернув обработчик, используемый клиентом, либо украсив стек обработчиков.

use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;

$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(add_header('X-Foo', 'bar'));
$client = new Client(['handler' => $stack]);

Теперь, когда вы отправляете запрос, клиент будет использовать обработчик, составленный с помощью добавленного вами промежуточного ПО, добавляя заголовок к каждому запросу.

Вот пример создания промежуточного ПО, которое изменяет ответ нижестоящего обработчика. В этом примере к ответу добавляется заголовок.

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;

function add_response_header($header, $value)
{
    return function (callable $handler) use ($header, $value) {
        return function (
            RequestInterface $request,
            array $options
        ) use ($handler, $header, $value) {
            $promise = $handler($request, $options);
            return $promise->then(
                function (ResponseInterface $response) use ($header, $value) {
                    return $response->withHeader($header, $value);
                }
            );
        };
    };
}

$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(add_response_header('X-Foo', 'bar'));
$client = new Client(['handler' => $stack]);

Создание промежуточного ПО, которое изменяет запрос, значительно упрощается с помощью промежуточного ПО GuzzleHttp\Middleware::mapRequest() промежуточного ПО. Это промежуточное ПО принимает функцию, которая принимает аргумент запроса и возвращает запрос для отправки.

use Psr\Http\Message\RequestInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;

$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());

$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
    return $request->withHeader('X-Foo', 'bar');
}));

$client = new Client(['handler' => $stack]);

Изменение ответа также значительно упрощается при использовании GuzzleHttp\Middleware::mapResponse() промежуточного ПО.

use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;

$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());

$stack->push(Middleware::mapResponse(function (ResponseInterface $response) {
    return $response->withHeader('X-Foo', 'bar');
}));

$client = new Client(['handler' => $stack]);

HandlerStack

Стек обработчиков представляет собой стек промежуточных программ для применения к базовой функции обработчика функции. Вы можете задвинуть промежуточное программное обеспечение в стек, чтобы добавить его в верхнюю часть стека, и вытеснять промежуточное ПО из стека, чтобы добавить его в нижнюю часть стека. Когда стек разрешается, обработчик заталкивается в стек. Каждое значение затем выталкивается из стека, обертывая предыдущее значение, вытащенное из стека. стек.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface;

$stack = new HandlerStack();
$stack->setHandler(Utils::chooseHandler());

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'A';
    return $r;
}));

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'B';
    return $r;
}));

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'C';
    return $r;
}));

$client->request('GET', 'http://httpbin.org/');
// echoes 'ABC';

$stack->unshift(Middleware::mapRequest(function (RequestInterface $r) {
    echo '0';
    return $r;
}));

$client = new Client(['handler' => $stack]);
$client->request('GET', 'http://httpbin.org/');
// echoes '0ABC';

Вы можете дать промежуточному ПО имя, что позволит вам добавить промежуточное ПО перед других именованных промежуточных программ, после других именованных промежуточных программ или удалить промежуточную программу по имени.

use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Middleware;

// Add a middleware with a name
$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Foo', 'Bar');
}, 'add_foo'));

// Add a middleware before a named middleware (unshift before).
$stack->before('add_foo', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Baz', 'Qux');
}, 'add_baz'));

// Add a middleware after a named middleware (pushed after).
$stack->after('add_baz', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Lorem', 'Ipsum');
}));

// Remove a middleware by name
$stack->remove('add_foo');

Создание обработчика

Как уже говорилось ранее, обработчик - это функция, принимающая в себя Psr\Http\Message\RequestInterface и массив опций запроса и возвращает GuzzleHttp\Promise\PromiseInterface, который выполняется с помощью Psr\Http\Message\ResponseInterface или отклоняется с исключением.

Обработчик отвечает за применение следующих опций запроса. Эти опции запроса являются подмножеством опций запроса, называемых "опции передачи".