

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Handler und Middleware in der Version 3 AWS SDK für PHP
<a name="guide_handlers-and-middleware"></a>

Der Hauptmechanismus für die Erweiterung von AWS SDK für PHP ist der Einsatz von **Handlern** und **Middleware**. Jede SDK-Client-Klasse besitzt eine `Aws\HandlerList`-Instance, die über die `getHandlerList()`-Methode eines Clients erreichbar ist. Sie können die `HandlerList` eines Clients abrufen und ändern, um Client-Verhaltensweisen hinzuzufügen oder zu entfernen.

## Handler
<a name="handlers"></a>

Ein Handler ist eine Funktion, die die eigentliche Transformation eines Befehls und einer Anfrage in ein Ergebnis durchführt. Ein Handler sendet typischerweise HTTP-Anfragen. Handler können mit Middleware konstruiert werden, um ihr Verhalten zu verbessern. Ein Handler ist eine Funktion, die eine `Aws\CommandInterface`und eine`Psr\Http\Message\RequestInterface` akzeptiert und ein Promise zurückgibt, das mit einer `Aws\ResultInterface` erfüllt oder mit einem `Aws\Exception\AwsException` Grund abgelehnt wird.

Hier ist ein Handler, der für jeden Aufruf das gleiche modellhafte Ergebnis liefert.

```
use Aws\CommandInterface;
use Aws\Result;
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Promise;

$myHandler = function (CommandInterface $cmd, RequestInterface $request) {
    $result = new Result(['foo' => 'bar']);
    return Promise\promise_for($result);
};
```

Sie können diesen Handler mit einem SDK-Client verwenden, indem Sie eine `handler`-Option im Konstruktor eines Clients angeben.

```
// Set the handler of the client in the constructor
$s3 = new Aws\S3\S3Client([
    'region'  => 'us-east-1',
    'version' => '2006-03-01',
    'handler' => $myHandler
]);
```

Sie können den Handler eines Clients auch ändern, nachdem er erstellt wurde. Dazu verwenden Sie die `setHandler`-Methode eines `Aws\ClientInterface`.

```
// Set the handler of the client after it is constructed
$s3->getHandlerList()->setHandler($myHandler);
```

**Anmerkung**  
Um den Handler eines Clients mit mehreren Regionen nach seiner Erstellung zu ändern, verwenden Sie die `useCustomHandler` Methode eines. `Aws\MultiRegionClient`  

```
$multiRegionClient->useCustomHandler($myHandler);
```

### Handler simulieren
<a name="mock-handler"></a>

Wir empfehlen die Verwendung von `MockHandler` bei der Erstellung von Tests, die das SDK verwenden. Du kannst den `Aws\MockHandler` benutzen, um modellhafte Ergebnisse zurückzugeben oder modellhafte Ausnahmen aufzuwerfen. Sie stellen Ergebnisse oder Ausnahmen in die Warteschlange und stellen sie dann in der MockHandler FIFO-Reihenfolge aus der Warteschlange.

```
use Aws\Result;
use Aws\MockHandler;
use Aws\DynamoDb\DynamoDbClient;
use Aws\CommandInterface;
use Psr\Http\Message\RequestInterface;
use Aws\Exception\AwsException;

$mock = new MockHandler();

// Return a mocked result
$mock->append(new Result(['foo' => 'bar']));

// You can provide a function to invoke; here we throw a mock exception
$mock->append(function (CommandInterface $cmd, RequestInterface $req) {
    return new AwsException('Mock exception', $cmd);
});

// Create a client with the mock handler
$client = new DynamoDbClient([
    'region'  => 'us-west-2',
    'version' => 'latest',
    'handler' => $mock
]);

// Result object response will contain ['foo' => 'bar']
$result = $client->listTables();

// This will throw the exception that was enqueued
$client->listTables();
```

## Middleware
<a name="middleware"></a>

Middleware ist eine spezielle Art von High-Level-Funktion, die das Verhalten bei der Übertragung eines Befehls erweitert und an einen „nächsten“ Handler delegiert. Middleware-Funktionen akzeptieren eine `Aws\CommandInterface` und eine `Psr\Http\Message\RequestInterface` und geben ein Promise zurück, das mit einer `Aws\ResultInterface`erfüllt oder mit einem `Aws\Exception\AwsException`-Grund abgelehnt wird.

Eine Middleware ist eine Funktion höherer Ordnung, die einen Befehl, eine Anforderung oder ein Ergebnis beim Durchlaufen der Middleware ändert. Ein Middleware hat die folgende Form.

```
use Aws\CommandInterface;
use Psr\Http\Message\RequestInterface;

$middleware = function () {
    return function (callable $handler) use ($fn) {
        return function (
            CommandInterface $command,
            RequestInterface $request = null
        ) use ($handler, $fn) {
            // Do something before calling the next handler
            // ...
            $promise = $fn($command, $request);
            // Do something in the promise after calling the next handler
            // ...
            return $promise;
        };
    };
};
```

Eine Middleware erhält einen Befehl zum Ausführen und ein optionales Anfrage-Objekt. Die Middleware kann die Anfrage und den Befehl erweitern oder sie unverändert lassen. Eine Middleware ruft dann das nächste Handle in der Kette auf oder kann den nächsten Handler kurzschließen und ein Promise zurückgeben. Das Promise, das durch den Aufruf des nächsten Handlers erzeugt wird, kann dann mit der Methode `then` des Promise erweitert werden, um das eventuelle Ergebnis oder den Fehler zu ändern, bevor das Promise zurück auf den Stack der Middleware gesendet wird.

### HandlerList
<a name="handlerlist"></a>

Das SDK verwendet eine `Aws\HandlerList` zum Verwalten der Middleware und der Handler, wenn es einen Befehl ausführt. Jeder SDK-Client besitzt eine `HandlerList`, und diese `HandlerList` wird geklont und jedem Befehl hinzugefügt, den ein Client erstellt. Sie können eine Middleware und einen Standard-Handler für jeden von einem Client erstellten Befehl anfügen, indem Sie eine Middleware zur `HandlerList` des Clients hinzufügen. Sie können Middleware zu bestimmten Befehlen hinzufügen oder entfernen, indem Sie die `HandlerList` für einen bestimmten Befehl ändern.

Eine `HandlerList` stellt einen Stack von Middleware dar, der verwendet wird, um einen **Handler** zu kapseln. Für die Verwaltung der Liste der Middleware und die Reihenfolge, in der sie einen Handler kapseln, unterteilt die `HandlerList` den Middleware-Stack in benannte Schritte, die Teil des Lebenszyklus der Übertragung eines Befehls sind:

1.  `init` – Standardparameter hinzufügen

1.  `validate` – Validieren der erforderlichen Parameter

1.  `build` – Serialisieren einer HTTP-Anforderung für das Senden

1.  `sign` – Signieren der serialisierten HTTP-Anforderung

1. <handler> (kein Schritt, aber führt die tatsächliche Übertragung durch)

**init**  
Dieser Lifecycle-Schritt stellt die Initialisierung eines Befehls dar, und eine Anforderung wurde noch nicht serialisiert. Dieser Schritt wird in der Regel verwendet, um einem Befehl Standardparameter hinzuzufügen.  
Sie können dem `init`-Schritt Middleware unter Verwendung der `appendInit`- und `prependInit`-Methoden hinzufügen, wobei `appendInit` die Middleware am Ende der `prepend`-Liste hinzufügt, während `prependInit` die Middleware am Anfang der `prepend`-Liste hinzufügt.  

```
use Aws\Middleware;

$middleware = Middleware::tap(function ($cmd, $req) {
    // Observe the step
});

// Append to the end of the step with a custom name
$client->getHandlerList()->appendInit($middleware, 'custom-name');
// Prepend to the beginning of the step
$client->getHandlerList()->prependInit($middleware, 'custom-name');
```

**validieren**  
Dieser Lebenszyklus-Schritt dient der Validierung der Eingabeparameter eines Befehls.  
Sie können dem `validate`-Schritt Middleware unter Verwendung der `appendValidate`- und `prependValidate`-Methoden hinzufügen, wobei `appendValidate` die Middleware am Ende der `validate`-Liste hinzufügt, während `prependValidate` die Middleware am Anfang der `validate`-Liste hinzufügt.  

```
use Aws\Middleware;

$middleware = Middleware::tap(function ($cmd, $req) {
    // Observe the step
});

// Append to the end of the step with a custom name
$client->getHandlerList()->appendValidate($middleware, 'custom-name');
// Prepend to the beginning of the step
$client->getHandlerList()->prependValidate($middleware, 'custom-name');
```

**build**  
Dieser Lebenszyklus-Schritt wird verwendet, um eine HTTP-Anforderung für den auszuführenden Befehl zu serialisieren. Nachgelagerte Lebenszyklus-Ereignisse erhalten einen Befehl und eine PSR-7 HTTP-Anforderung.  
Sie können dem `build`-Schritt Middleware unter Verwendung der `appendBuild`- und `prependBuild`-Methoden hinzufügen, wobei `appendBuild` die Middleware am Ende der `build`-Liste hinzufügt, während `prependBuild` die Middleware am Anfang der `build`-Liste hinzufügt.  

```
use Aws\Middleware;

$middleware = Middleware::tap(function ($cmd, $req) {
    // Observe the step
});

// Append to the end of the step with a custom name
$client->getHandlerList()->appendBuild($middleware, 'custom-name');
// Prepend to the beginning of the step
$client->getHandlerList()->prependBuild($middleware, 'custom-name');
```

**sign**  
Dieser Lebenszyklus-Schritt wird normalerweise verwendet, um eine HTTP-Anforderung zu signieren, bevor sie gesendet wird. Um Signaturfehler zu vermeiden, sollten Sie davon absehen, eine HTTP-Anforderung zu ändern, nachdem sie signiert wurde.  
Dies ist der letzte Schritt in der `HandlerList`, bevor die HTTP-Anforderung durch einen Handler übertragen wird.  
Sie können dem `sign`-Schritt Middleware unter Verwendung der `appendSign`- und `prependSign`-Methoden hinzufügen, wobei `appendSign` die Middleware am Ende der `sign`-Liste hinzufügt, während `prependSign` die Middleware am Anfang der `sign`-Liste hinzufügt.  

```
use Aws\Middleware;

$middleware = Middleware::tap(function ($cmd, $req) {
    // Observe the step
});

// Append to the end of the step with a custom name
$client->getHandlerList()->appendSign($middleware, 'custom-name');
// Prepend to the beginning of the step
$client->getHandlerList()->prependSign($middleware, 'custom-name');
```

### Verfügbare Middleware
<a name="available-middleware"></a>

Das SDK bietet verschiedene Middleware, den Sie verwenden können, um das Verhalten eines Clients oder die Ausführung eines Befehls zu erweitern.

#### mapCommand
<a name="map-command"></a>

Die `Aws\Middleware::mapCommand` Middleware ist nützlich, wenn Sie einen Befehl ändern müssen, bevor der Befehl als HTTP-Anforderung serialisiert wird. Beispielsweise kann `mapCommand` verwendet werden, um eine Validierung durchzuführen oder Standardparameter hinzuzufügen. Die `mapCommand`-Funktion akzeptiert eine aufrufbare Funktion, die ein `Aws\CommandInterface`-Objekt entgegennimmt und ein `Aws\CommandInterface`-Objekt zurückgibt.

```
use Aws\Middleware;
use Aws\CommandInterface;

// Here we've omitted the require Bucket parameter. We'll add it in the
// custom middleware.
$command = $s3Client->getCommand('HeadObject', ['Key' => 'test']);

// Apply a custom middleware named "add-param" to the "init" lifecycle step
$command->getHandlerList()->appendInit(
    Middleware::mapCommand(function (CommandInterface $command) {
        $command['Bucket'] = 'amzn-s3-demo-bucket';
        // Be sure to return the command!
        return $command;
    }),
    'add-param'
);
```

#### mapRequest
<a name="map-request"></a>

Die `Aws\Middleware::mapRequest` Middleware ist nützlich, wenn Sie einen Befehl ändern müssen, nachdem er serialisiert wurde, aber bevor er gesendet wird. Beispielsweise kann sie verwendet werden, um einer Anforderung benutzerdefinierte HTTP-Header hinzuzufügen. Die `mapRequest`-Funktion akzeptiert eine aufrufbare Funktion, die ein `Psr\Http\Message\RequestInterface`-Argument entgegennimmt und ein `Psr\Http\Message\RequestInterface`-Objekt zurückgibt.

```
use Aws\Middleware;
use Psr\Http\Message\RequestInterface;

// Create a command so that we can access the handler list
$command = $s3Client->getCommand('HeadObject', [
    'Key'    => 'test',
    'Bucket' => 'amzn-s3-demo-bucket'
]);

// Apply a custom middleware named "add-header" to the "build" lifecycle step
$command->getHandlerList()->appendBuild(
    Middleware::mapRequest(function (RequestInterface $request) {
        // Return a new request with the added header
        return $request->withHeader('X-Foo-Baz', 'Bar');
    }),
    'add-header'
);
```

Wenn der Befehl ausgeführt wird, wird er mit dem benutzerdefinierten Header gesendet.

**Wichtig**  
Beachten Sie, dass die Middleware der Handler-Liste am Ende des `build`-Schritts hinzugefügt wurde. Damit soll sichergestellt werden, dass eine Anforderung erstellt wurde, bevor diese Middleware aufgerufen wird.

#### mapResult
<a name="mapresult"></a>

Die `Aws\Middleware::mapResult` Middleware ist nützlich, wenn Sie das Ergebnis einer Befehlsausführung ändern müssen. Die `mapResult`-Funktion akzeptiert eine aufrufbare Funktion, die ein `Aws\ResultInterface`-Argument entgegennimmt und ein `Aws\ResultInterface`-Objekt zurückgibt.

```
use Aws\Middleware;
use Aws\ResultInterface;

$command = $s3Client->getCommand('HeadObject', [
    'Key'    => 'test',
    'Bucket' => 'amzn-s3-demo-bucket'
]);

$command->getHandlerList()->appendSign(
    Middleware::mapResult(function (ResultInterface $result) {
        // Add a custom value to the result
        $result['foo'] = 'bar';
        return $result;
    })
);
```

Wenn der Befehl ausgeführt wird, enthält das zurückgegebene Ergebnis ein `foo`-Attribut.

#### history
<a name="history"></a>

Die `history` Middleware ist nützlich zum Testen, ob das SDK die Befehle ausgeführt hat, wie erwartet, ob es die HTTP-Anforderungen gesendet hat, wie erwartet, und ob die Ergebnisse erzeugt wurden, wie erwartet. Es ist im Wesentlichen eine Middleware, die sich ähnlich verhält wie der Verlauf eines Web-Browsers.

```
use Aws\History;
use Aws\Middleware;

$ddb = new Aws\DynamoDb\DynamoDbClient([
    'version' => 'latest',
    'region'  => 'us-west-2'
]);

// Create a history container to store the history data
$history = new History();

// Add the history middleware that uses the history container
$ddb->getHandlerList()->appendSign(Middleware::history($history));
```

Ein `Aws\History`-Verlaufscontainer speichert standardmäßig 10 Einträge, bevor er Einträge löscht. Sie können die Anzahl der Einträge anpassen, indem Sie die Anzahl der beizubehaltenden Einträge an den Konstruktor übergeben.

```
// Create a history container that stores 20 entries
$history = new History(20);
```

Sie können den Verlaufscontainer nach der Ausführung von Anforderungen, die die Verlaufs-Middleware durchlaufen, überprüfen.

```
// The object is countable, returning the number of entries in the container
count($history);

// The object is iterable, yielding each entry in the container
foreach ($history as $entry) {
    // You can access the command that was executed
    var_dump($entry['command']);
    // The request that was serialized and sent
    var_dump($entry['request']);
    // The result that was received (if successful)
    var_dump($entry['result']);
    // The exception that was received (if a failure occurred)
    var_dump($entry['exception']);
}

// You can get the last Aws\CommandInterface that was executed. This method
// will throw an exception if no commands have been executed.
$command = $history->getLastCommand();

// You can get the last request that was serialized. This method will throw an exception
// if no requests have been serialized.
$request = $history->getLastRequest();

// You can get the last return value (an Aws\ResultInterface or Exception).
// The method will throw an exception if no value has been returned for the last
// executed operation (e.g., an async request has not completed).
$result = $history->getLastReturn();

// You can clear out the entries using clear
$history->clear();
```

#### tap
<a name="tap"></a>

Die `tap` Middleware wird als Beobachter verwendet. Sie können diese Middleware verwenden, um Funktionen aufzurufen, wenn Sie Befehle durch die Middleware-Kette senden. Die `tap` Funktion akzeptiert eine aufrufbare Funktion, die die `Aws\CommandInterface` entgegennimmt, ebenso wie eine optionale `Psr\Http\Message\RequestInterface`, die gerade ausgeführt wird.

```
use Aws\Middleware;

$s3 = new Aws\S3\S3Client([
    'region'  => 'us-east-1',
    'version' => '2006-03-01'
]);

$handlerList = $s3->getHandlerList();

// Create a tap middleware that observes the command at a specific step
$handlerList->appendInit(
    Middleware::tap(function (CommandInterface $cmd, RequestInterface $req = null) {
        echo 'About to send: ' . $cmd->getName() . "\n";
        if ($req) {
            echo 'HTTP method: ' . $request->getMethod() . "\n";
        }
    }
);
```

## Benutzerdefinierte Handler erstellen
<a name="creating-custom-handlers"></a>

Ein Handler ist einfach eine Funktion, die ein `Aws\CommandInterface`-Objekt und ein `Psr\Http\Message\RequestInterface`-Objekt entgegennimmt und eine `GuzzleHttp\Promise\PromiseInterface` zurückgibt, die mit einer `Aws\ResultInterface` erfüllt oder mit einer `Aws\Exception\AwsException` abgelehnt wird.

Obwohl das SDK hat mehrere `@http`-Optionen bietet, muss ein Handler nur wissen, wie die folgenden Optionen verwendet werden:
+  [connect\_timeout](guide_configuration.md#http-connect-timeout) 
+  [debug](guide_configuration.md#http-debug) 
+  [decode\_content](guide_configuration.md#http-decode-content) (optional)
+  [Verzögerung](guide_configuration.md#http-delay) 
+  [progress](guide_configuration.md#http-progress) (optional)
+  [proxy](guide_configuration.md#http-proxy) 
+  [sink](guide_configuration.md#http-sink) 
+  [synchronous](guide_configuration.md#http-sync) (optional)
+  [stream](guide_configuration.md#http-stream) (optional)
+  [timeout](guide_configuration.md#http-timeout) 
+  [verify](guide_configuration.md#http-verify) 
+ http\_stats\_receiver (optional) – Eine Funktion zum Aufrufen mit einem assoziativen Array von HTTP-Übertragungsstatistiken, wenn Sie über den [stats](guide_configuration.md#config-stats)-Konfigurationsparameter angefordert wurden.

Wenn die Option nicht als optional angegeben ist, MUSS ein Handler in der Lage sein, die Option zu verarbeiten, oder er MUSS ein abgelehntes Promise zurückgeben.

Zusätzlich zur Behandlung bestimmter `@http` Optionen MUSS ein Handler einen `User-Agent` Header hinzufügen, der die folgende Form hat, wobei „3.X“ durch ersetzt werden kann `Aws\Sdk::VERSION` und „HandlerSpecificData/version...“ durch Ihre handlerspezifische User-Agent-Zeichenfolge ersetzt werden sollte.

 `User-Agent: aws-sdk-php/3.X HandlerSpecificData/version ...` 