Handler und Middleware

Guzzle-Clients verwenden einen Handler und ein Middleware-System, um HTTP-Anfragen zu senden.

Handler

Eine Handler-Funktion akzeptiert ein Psr\Http\Message\RequestInterface und ein Array von Anfrageoptionen und gibt ein GuzzleHttp\Promise\PromiseInterface zurück, das mit einem Psr\Http\Message\ResponseInterface erfüllt oder mit einer Ausnahme.

Sie können einem Client einen benutzerdefinierten Handler zur Verfügung stellen, indem Sie die Option handler des eines Client-Konstruktors. Es ist wichtig zu verstehen, dass mehrere von Guzzle verwendete Request Optionen, die von Guzzle verwendet werden, erfordern, dass bestimmte Middlewares den vom Client verwendeten Handler vom Client verwendet wird. Sie können sicherstellen, dass der Handler, den Sie einem Client zur Verfügung stellen, die Standard-Middlewares verwendet, indem Sie den Handler in die GuzzleHttp\HandlerStack::create(callable $handler = null) statische Methode.

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

Die Methode create fügt dem HandlerStack Standard-Handler hinzu. Wenn der HandlerStack aufgelöst wird, werden die Handler in der folgenden Reihenfolge ausgeführt:

  1. Anfrage absenden:
  1. http_errors - No op beim Senden einer Anfrage. Der Antwort-Statuscode wird bei der Antwortverarbeitung geprüft, wenn ein Antwortversprechen auf dem den Stack zurückgibt.
  2. allow_redirects - Keine Option beim Senden einer Anfrage. Folgende Redirects erfolgt, wenn ein Antwortversprechen auf dem Stack zurückgegeben wird.
  3. cookies - Fügt Cookies zu Anfragen hinzu.
  4. prepare_body - Der Body einer HTTP-Anfrage wird vorbereitet (z.B., Standard-Header wie Content-Length, Content-Type, etc. hinzufügen).
  5. <Anfrage mit Handler senden>
  1. Bearbeitung der Antwort:
  1. prepare_body - kein Einsatz bei der Antwortverarbeitung.
  2. cookies - extrahiert Antwort-Cookies in die Keksdose.
  3. allow_redirects - Folgt Umleitungen.
  4. http_errors - löst Ausnahmen aus, wenn der Antwortstatus code >= 400.

Wenn kein $handler Argument angegeben wird, wählt GuzzleHttp\HandlerStack::create() wählt den am besten geeigneten Handler auf der Grundlage der auf Ihrem System verfügbaren Erweiterungen Ihrem System.

Wichtig

Der einem Client zur Verfügung gestellte Handler bestimmt, wie die Anfrageoptionen und für jede von einem Client gesendete Anfrage genutzt werden. Zum Beispiel, wenn Sie keine keine Cookie-Middleware mit einem Client assoziiert haben, dann wird das Setzen der cookies keine Auswirkung auf die Anfrage.

Middleware

Die Middleware erweitert die Funktionalität der Handler, indem sie diese bei der Prozess der Erzeugung von Antworten aufruft. Middleware ist als eine Funktion höherer Ordnung implementiert Funktion implementiert, die die folgende Form hat.

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-Funktionen geben eine Funktion zurück, die den nächsten aufzurufenden Handler annimmt. Diese zurückgegebene Funktion gibt dann eine andere Funktion zurück, die als zusammengesetzte Handler fungiert - sie nimmt eine Anfrage und Optionen an und gibt ein Versprechen zurück, das mit einer Antwort erfüllt wird. Ihre komponierte Middleware kann die Anfrage ändern, benutzerdefinierte Anforderungsoptionen hinzufügen und das Versprechen ändern, das von der nachgeschalteten Handler zurückgegeben wird.

Hier ist ein Beispiel für das Hinzufügen einer Kopfzeile zu jeder Anfrage.

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

Sobald eine Middleware erstellt wurde, können Sie sie zu einem Client hinzufügen, indem Sie entweder den vom Client verwendeten Handler verpacken oder einen Handler-Stack dekorieren.

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

Wenn Sie nun eine Anfrage senden, verwendet der Client einen Handler, der aus der von Ihnen hinzugefügten Middleware besteht und jeder Anfrage eine Kopfzeile hinzufügt.

Hier ein Beispiel für die Erstellung einer Middleware, die die Antwort des Downstream-Handlers ändert. In diesem Beispiel wird der Antwort eine Kopfzeile hinzugefügt.

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

Die Erstellung einer Middleware, die eine Anfrage modifiziert, wird durch die Verwendung der GuzzleHttp\Middleware::mapRequest() Middleware. Diese Middleware akzeptiert eine Funktion, die das Argument request annimmt und die zu sendende Anfrage zurückgibt.

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

Die Änderung einer Antwort ist auch viel einfacher mit der 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

Ein Handler-Stapel stellt einen Stapel von Middleware dar, der auf eine Basis-Handler Funktion. Sie können Middleware auf den Stapel schieben, um sie oben auf dem Stapel hinzuzufügen, und Middleware aus dem Stapel entfernen, um sie am unteren Ende des Stapels hinzuzufügen. Wenn der Stapel aufgelöst wird, wird der Handler auf den Stapel geschoben. Jeder Wert wird dann vom Stapel gepoppt, wobei der vorherige Wert, der vom Stapel gepoppt wurde, um den Stapel.

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

Sie können Middleware einen Namen geben, der es Ihnen ermöglicht, Middleware vor andere benannte Middleware hinzuzufügen, nach anderer benannter Middleware, oder Middleware zu entfernen nach Namen.

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

Erstellen eines Handlers

Wie bereits erwähnt, ist ein Handler eine Funktion, die eine Psr\Http\Message\RequestInterface und ein Array von Anfrageoptionen und gibt ein GuzzleHttp\Promise\PromiseInterface, das mit einem Psr\Http\Message\ResponseInterface erfüllt oder mit einer Ausnahme abgelehnt wird.

Ein Handler ist für die Anwendung der folgenden Anfrageoptionen verantwortlich. Diese Anfrageoptionen sind eine Untergruppe der Anfrageoptionen, die "Übertragungsoptionen".