Handlers et intergiciels

Les clients de Guzzle utilisent un gestionnaire et un système de middleware pour envoyer des requêtes HTTP.

Handlers

Une fonction de gestion accepte un Psr\Http\Message\RequestInterface et un tableau de options de la requête et renvoie un GuzzleHttp\Promise\PromiseInterface qui est satisfait par une Psr\Http\Message\ResponseInterface ou rejeté par une exception. exception.

Vous pouvez fournir un gestionnaire personnalisé à un client à l'aide de l'option gestionnaire du constructeur du client. un constructeur de client. Il est important de comprendre que plusieurs options de requête options de requête utilisées par Guzzle exigent que des intergiciels spécifiques enveloppent le gestionnaire utilisé par le client. Vous pouvez vous assurer que le gestionnaire que vous fournissez à un client utilise les middlewares par défaut en enveloppant le gestionnaire dans une enveloppe. par défaut en enveloppant le gestionnaire dans la balise GuzzleHttp\HandlerStack::create(callable $handler = null) méthode statique.

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

La méthode create ajoute des gestionnaires par défaut à la HandlerStack. Lorsque la HandlerStack est résolue, les gestionnaires s'exécutent dans l'ordre suivant :

  1. Envoi de la demande :
  1. http_errors - Aucune opération lors de l'envoi d'une requête. Le code d'état de la réponse est vérifié dans le traitement de la réponse lors du retour d'une promesse de réponse dans la pile. la pile.
  2. allow_redirects - Pas d'opération lors de l'envoi d'une requête. Suivre les redirections se produit lorsqu'une promesse de réponse est renvoyée sur la pile.
  3. cookies - Ajoute des cookies aux requêtes.
  4. prepare_body - Le corps d'une requête HTTP sera préparé (par ex, ajouter des en-têtes par défaut comme Content-Length, Content-Type, etc.)
  5. <send request with handler> ;
  1. Réponse du traitement :
  1. prepare_body - aucune opération sur le traitement des réponses.
  2. cookies - extrait les cookies de réponse dans la boîte à cookies.
  3. allow_redirects - Suit les redirections.
  4. http_errors - lève des exceptions lorsque le code d'état de la réponse >= 400.

Lorsqu'aucun argument $handler n'est fourni, GuzzleHttp\HandlerStack::create() choisira le gestionnaire le plus approprié en fonction des extensions disponibles sur votre système. votre système.

Important

Le gestionnaire fourni à un client détermine comment les options de demande sont appliquées et utilisées pour chaque demande envoyée par un client. Par exemple, si vous n'avez pas n'avez pas d'intergiciel de cookies associé à un client, alors la définition de l'option cookies n'aura aucun effet sur la demande.

Middleware

L'intergiciel augmente la fonctionnalité des gestionnaires en les invoquant dans le processus de génération des réponses. processus de génération des réponses. L'intergiciel est implémenté comme une fonction d'ordre supérieur d'ordre supérieur qui prend la forme suivante.

use Psr\Http\Message\RequestInterface;

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

Les fonctions d'intergiciel renvoient une fonction qui accepte le prochain gestionnaire à invoquer. Cette fonction renvoie ensuite une autre fonction qui agit comme un gestionnaire composé. composé - elle accepte une demande et des options, et renvoie une promesse qui est promesse qui est remplie avec une réponse. Votre intergiciel composé peut modifier la demande, ajouter des options personnalisées et modifier la promesse renvoyée par le gestionnaire en aval. en aval.

Voici un exemple d'ajout d'un en-tête à chaque requête.

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

Une fois qu'un intergiciel a été créé, vous pouvez l'ajouter à un client soit en enveloppant le gestionnaire utilisé par le client, soit en décorant une pile de gestionnaires.

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

Maintenant, lorsque vous envoyez une demande, le client utilisera un gestionnaire composé avec votre intergiciel ajouté, ajoutant un en-tête à chaque demande.

Voici un exemple de création d'un intergiciel qui modifie la réponse du gestionnaire en aval. Cet exemple ajoute un en-tête à la réponse.

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

La création d'un middleware qui modifie une requête est rendue beaucoup plus simple grâce à la fonction L'intergiciel GuzzleHttp\Middleware::mapRequest(). Cet intergiciel accepte une fonction qui prend l'argument de la requête et renvoie la requête à envoyer.

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

La modification d'une réponse est également beaucoup plus simple en utilisant l'intergiciel 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

Une pile de gestionnaires représente une pile d'intergiciels à appliquer à une fonction de gestionnaire de base. de base. Vous pouvez pousser l'intergiciel sur la pile pour l'ajouter au sommet de la pile, et déporter un intergiciel sur la pile pour l'ajouter au bas de la pile. Lorsque la pile est résolue, le gestionnaire est poussé sur la pile. Chaque valeur est est ensuite retirée de la pile, enveloppant la valeur précédente retirée de la pile. pile.

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

Vous pouvez donner un nom à l'intergiciel, ce qui vous permet d'ajouter l'intergiciel avant, après ou après d'autres intergiciels nommés. d'autres middleware nommés, après d'autres middleware nommés, ou de supprimer des middleware par nom.

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

Créer un gestionnaire

Comme indiqué précédemment, un gestionnaire est une fonction qui accepte une Psr\Http\Message\RequestInterface et un tableau d'options de requête et retourne un GuzzleHttp\Promise\PromiseInterface qui est rempli avec un Psr\Http\Message\ResponseInterface ou rejeté avec une exception.

Un gestionnaire est chargé d'appliquer les Options de demande suivantes. Ces options de demande sont un sous-ensemble d'options de demande appelé "options de transfert".