Оглавление

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

Обработчики

Функция-обработчик принимает 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); // Заворачивать в w/ промежуточный слой 
$client = new Client(['handler' => $stack]);

 

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

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

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

Важно

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

Промежуточный слой.

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

use Psr\Http\Message\RequestInterface;

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

 

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

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

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);
        };
    };
}

Once a middleware has been created, you can add it to a client by either wrapping the handler used by the client or by decorating a handler stack.

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]);

 

Now when you send a request, the client will use a handler composed with your added middleware, adding a header to each request.

Here's an example of creating a middleware that modifies the response of the downstream handler. This example adds a header to the response.

 

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]);

 

Creating a middleware that modifies a request is made much simpler using the GuzzleHttp\Middleware::mapRequest() middleware. This middleware accepts a function that takes the request argument and returns the request to send.

 

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]);

 

Modifying a response is also much simpler using the GuzzleHttp\Middleware::mapResponse() middleware.

 

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

A handler stack represents a stack of middleware to apply to a base handler function. You can push middleware to the stack to add to the top of the stack, and unshift middleware onto the stack to add to the bottom of the stack. When the stack is resolved, the handler is pushed onto the stack. Each value is then popped off of the stack, wrapping the previous value popped off of the stack.

 

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

$stack = new HandlerStack();
$stack->setHandler(\GuzzleHttp\choose_handler());

$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';

 

You can give middleware a name, which allows you to add middleware before other named middleware, after other named middleware, or remove middleware by name.

 

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

// Добавить промежуточное программное обеспечение с именем
$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Foo', 'Bar');
}, 'add_foo');

// Добавить промежуточное программное обеспечение перед 
// именованным промежуточным программным обеспечением (отмените смещение перед этим).
$stack->before('add_foo', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Baz', 'Qux');
}, 'add_baz');

// Добавьте промежуточное программное обеспечение после 
// именованного промежуточного программного обеспечения (нажатого после).
$stack->after('add_baz', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Lorem', 'Ipsum');
});

// Удаление промежуточного программного обеспечения по имени
$stack->remove('add_foo');

 

Creating a Handler

As stated earlier, a handler is a function accepts a Psr\Http\Message\RequestInterface and array of request options and returns a GuzzleHttp\Promise\PromiseInterface that is fulfilled with a Psr\Http\Message\ResponseInterface or rejected with an exception.

A handler is responsible for applying the following Request Options. These request options are a subset of request options called "transfer options".

Оглавление