Handlers και Middleware

Οι πελάτες του Guzzle χρησιμοποιούν ένα σύστημα χειρισμού και ενδιάμεσου λογισμικού για την αποστολή αιτημάτων HTTP.

Χειριστές

Μια συνάρτηση χειρισμού δέχεται μια Psr\Http\Message\RequestInterface και έναν πίνακα από επιλογών αίτησης και επιστρέφει ένα GuzzleHttp\Promise\PromiseInterface που είναι ικανοποιείται με μια Psr\Http\Message\ResponseInterface ή απορρίπτεται με μια exception.

Μπορείτε να παρέχετε έναν προσαρμοσμένο χειριστή σε έναν πελάτη χρησιμοποιώντας την επιλογή 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 - Δεν υπάρχει op κατά την αποστολή μιας αίτησης. Ο κωδικός κατάστασης απόκρισης ελέγχεται κατά την επεξεργασία της απάντησης κατά την επιστροφή μιας υπόσχεσης απάντησης μέχρι στη στοίβα.
  2. allow_redirects - Δεν υπάρχει op κατά την αποστολή μιας αίτησης. Ακολουθούν ανακατευθύνσεις συμβαίνει όταν επιστρέφεται μια υπόσχεση απάντησης προς τα πάνω στη στοίβα.
  3. cookies - Προσθέτει cookies στις αιτήσεις.
  4. prepare_body - Το σώμα μιας αίτησης HTTP θα προετοιμαστεί (π.χ., προσθήκη προεπιλεγμένων επικεφαλίδων όπως Content-Length, Content-Type, κ.λπ.).
  5. <send request with handler>,
  1. Απάντηση επεξεργασίας:
  1. prepare_body - no op on response processing.
  2. cookies - εξάγει τα cookies απόκρισης στο βάζο με τα cookies.
  3. allow_redirects - Ακολουθεί τις ανακατευθύνσεις.
  4. http_errors - πετάει εξαιρέσεις όταν ο κωδικός κατάστασης απόκρισης >= 400.

Όταν δεν παρέχεται κανένα όρισμα $handler, GuzzleHttp\HandlerStack::create() θα επιλέξει τον καταλληλότερο χειριστή με βάση τις διαθέσιμες επεκτάσεις στο στο σύστημά σας.

Σημαντικό

Ο χειριστής που παρέχεται σε έναν πελάτη καθορίζει τον τρόπο εφαρμογής των επιλογών αίτησης και χρησιμοποιούνται για κάθε αίτηση που αποστέλλεται από έναν πελάτη. Για παράδειγμα, εάν δεν έχετε ένα ενδιάμεσο λογισμικό cookie που σχετίζεται με έναν πελάτη, τότε ο καθορισμός του cookies επιλογή αίτησης δεν θα έχει καμία επίδραση στην αίτηση.

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 επιστρέφουν μια συνάρτηση που δέχεται τον επόμενο χειριστή προς κλήση. Αυτή η επιστρεφόμενη συνάρτηση επιστρέφει στη συνέχεια μια άλλη συνάρτηση που λειτουργεί ως σύνθετη χειριστής - δέχεται ένα αίτημα και επιλογές και επιστρέφει μια υπόσχεση που είναι εκπληρώνεται με μια απάντηση. Το σύνθετο ενδιάμεσο λογισμικό σας μπορεί να τροποποιήσει την αίτηση, να προσθέσει προσαρμοσμένες επιλογές αίτησης και να τροποποιήσει την υπόσχεση που επιστρέφεται από τον μεταγενέστερο handler.

Ακολουθεί ένα παράδειγμα προσθήκης μιας επικεφαλίδας σε κάθε αίτηση.

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() middleware. Αυτό το middleware δέχεται μια συνάρτηση που δέχεται το όρισμα request και επιστρέφει το αίτημα προς αποστολή.

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() 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

Μια στοίβα χειριστών αντιπροσωπεύει μια στοίβα ενδιάμεσου λογισμικού για την εφαρμογή σε έναν βασικό χειριστή λειτουργία. Μπορείτε να ωθήσετε middleware στη στοίβα για να το προσθέσετε στην κορυφή της στοίβας, και να αφαιρέσετε middleware από τη στοίβα για να το προσθέσετε στο κάτω μέρος της στοίβας. Όταν η στοίβα επιλύεται, ο χειριστής μετατοπίζεται στη στοίβα. Κάθε τιμή είναι στη συνέχεια αφαιρείται από τη στοίβα, τυλίγοντας την προηγούμενη τιμή που αφαιρείται από τη stack.

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

Μπορείτε να δώσετε στο middleware ένα όνομα, το οποίο σας επιτρέπει να προσθέσετε middleware πριν άλλο ονομασμένο middleware, μετά από άλλο ονομασμένο middleware, ή να αφαιρέσετε middleware με βάση το όνομα.

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 ή απορρίπτεται με μια εξαίρεση.

Ένας χειριστής είναι υπεύθυνος για την εφαρμογή των ακόλουθων Επιλογές αίτησης. Αυτές οι επιλογές αίτησης είναι ένα υποσύνολο των επιλογών αίτησης που ονομάζονται "επιλογές μεταφοράς".