

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Handler dan middleware di Versi 3 AWS SDK untuk PHP
<a name="guide_handlers-and-middleware"></a>

**Mekanisme utama untuk memperluas AWS SDK untuk PHP adalah melalui **handler** dan middleware.** Setiap kelas klien SDK memiliki `Aws\HandlerList` instance yang dapat diakses melalui `getHandlerList()` metode klien. Anda dapat mengambil klien `HandlerList` dan memodifikasinya untuk menambah atau menghapus perilaku klien.

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

Handler adalah fungsi yang melakukan transformasi aktual dari perintah dan permintaan menjadi hasil. Handler biasanya mengirimkan permintaan HTTP. Handler dapat disusun dengan middleware untuk meningkatkan perilaku mereka. Handler adalah fungsi yang menerima `Aws\CommandInterface` dan a `Psr\Http\Message\RequestInterface` dan mengembalikan janji yang dipenuhi dengan `Aws\ResultInterface` atau ditolak dengan alasan. `Aws\Exception\AwsException`

Berikut adalah handler yang mengembalikan hasil tiruan yang sama untuk setiap panggilan.

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

Anda kemudian dapat menggunakan handler ini dengan klien SDK dengan memberikan `handler` opsi di konstruktor klien.

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

Anda juga dapat mengubah handler klien setelah dibangun menggunakan `setHandler` metode. `Aws\ClientInterface`

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

**catatan**  
Untuk mengubah handler klien multi-wilayah setelah dibangun, gunakan `useCustomHandler` metode. `Aws\MultiRegionClient`  

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

### Pawang tiruan
<a name="mock-handler"></a>

Sebaiknya gunakan `MockHandler` saat menulis tes yang menggunakan SDK. Anda dapat menggunakan `Aws\MockHandler` untuk mengembalikan hasil yang diejek atau melempar pengecualian tiruan. Anda mengantrekan hasil atau pengecualian, dan MockHandler mengantrekannya dalam urutan FIFO.

```
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 adalah jenis khusus dari fungsi tingkat tinggi yang menambah perilaku mentransfer perintah, dan mendelegasikan ke handler “berikutnya”. Fungsi middleware menerima `Aws\CommandInterface` dan `Psr\Http\Message\RequestInterface` dan mengembalikan janji yang dipenuhi dengan `Aws\ResultInterface` atau ditolak dengan alasan. `Aws\Exception\AwsException`

Middleware adalah fungsi tingkat tinggi yang memodifikasi perintah, permintaan, atau hasil saat melewati middleware. Middleware mengambil bentuk berikut.

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

Middleware menerima perintah untuk mengeksekusi dan objek permintaan opsional. Middleware dapat memilih untuk menambah permintaan dan perintah atau membiarkannya apa adanya. Middleware kemudian memanggil pegangan berikutnya dalam rantai atau dapat memilih untuk melakukan hubungan pendek pada handler berikutnya dan mengembalikan janji. Janji yang dibuat dengan memanggil handler berikutnya kemudian dapat ditambah menggunakan `then` metode janji untuk memodifikasi hasil atau kesalahan akhirnya sebelum mengembalikan janji mencadangkan tumpukan middleware.

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

SDK menggunakan `Aws\HandlerList` untuk mengelola middleware dan handler yang digunakan saat menjalankan perintah. Setiap klien SDK memiliki`HandlerList`, dan ini `HandlerList` dikloning dan ditambahkan ke setiap perintah yang dibuat klien. Anda dapat melampirkan middleware dan handler default untuk digunakan untuk setiap perintah yang dibuat oleh klien dengan menambahkan middleware ke klien. `HandlerList` Anda dapat menambah dan menghapus middleware dari perintah tertentu dengan memodifikasi yang `HandlerList` dimiliki oleh perintah tertentu.

**A `HandlerList` merupakan tumpukan middleware yang digunakan untuk membungkus handler.** Untuk membantu mengelola daftar middleware dan urutan di mana mereka membungkus handler, `HandlerList` memecah tumpukan middleware menjadi langkah-langkah bernama yang mewakili bagian dari siklus hidup mentransfer perintah:

1.  `init`- Tambahkan parameter default

1.  `validate`- Validasi parameter yang diperlukan

1.  `build`- Serialisasi permintaan HTTP untuk mengirim

1.  `sign`- Tanda tangani permintaan HTTP serial

1. <handler>(bukan langkah, tetapi melakukan transfer yang sebenarnya)

**inisialisasi**  
Langkah siklus hidup ini mewakili inisialisasi perintah, dan permintaan belum diserialisasi. Langkah ini biasanya digunakan untuk menambahkan parameter default ke perintah.  
Anda dapat menambahkan middleware ke `init` langkah menggunakan `prependInit` metode `appendInit` dan, di mana `appendInit` menambahkan middleware ke akhir `prepend` daftar sambil `prependInit` menambahkan middleware ke bagian depan daftar. `prepend`  

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

**validasi**  
Langkah siklus hidup ini digunakan untuk memvalidasi parameter input dari sebuah perintah.  
Anda dapat menambahkan middleware ke `validate` langkah menggunakan `prependValidate` metode `appendValidate` dan, di mana `appendValidate` menambahkan middleware ke akhir `validate` daftar sambil `prependValidate` menambahkan middleware ke bagian depan daftar. `validate`  

```
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**  
Langkah siklus hidup ini digunakan untuk membuat serial permintaan HTTP untuk perintah yang sedang dijalankan. Acara siklus hidup hilir akan menerima perintah dan permintaan HTTP PSR-7.  
Anda dapat menambahkan middleware ke `build` langkah menggunakan `prependBuild` metode `appendBuild` dan, di mana `appendBuild` menambahkan middleware ke akhir `build` daftar sambil `prependBuild` menambahkan middleware ke bagian depan daftar. `build`  

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

**tanda tangan**  
Langkah siklus hidup ini biasanya digunakan untuk menandatangani permintaan HTTP sebelum dikirim melalui kawat. Anda biasanya harus menahan diri dari mutasi permintaan HTTP setelah ditandatangani untuk menghindari kesalahan tanda tangan.  
Ini adalah langkah terakhir `HandlerList` sebelum permintaan HTTP ditransfer oleh handler.  
Anda dapat menambahkan middleware ke `sign` langkah menggunakan `prependSign` metode `appendSign` dan, di mana `appendSign` menambahkan middleware ke akhir `sign` daftar sambil `prependSign` menambahkan middleware ke bagian depan daftar. `sign`  

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

### Middleware yang tersedia
<a name="available-middleware"></a>

SDK menyediakan beberapa middleware yang dapat Anda gunakan untuk meningkatkan perilaku klien atau untuk mengamati eksekusi perintah.

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

`Aws\Middleware::mapCommand`Middleware berguna ketika Anda perlu memodifikasi perintah sebelum perintah diserialisasi sebagai permintaan HTTP. Misalnya, `mapCommand` dapat digunakan untuk melakukan validasi atau menambahkan parameter default. `mapCommand`Fungsi menerima callable yang menerima `Aws\CommandInterface` objek dan mengembalikan objek. `Aws\CommandInterface`

```
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>

`Aws\Middleware::mapRequest`Middleware berguna ketika Anda perlu memodifikasi permintaan setelah serial tetapi sebelum dikirim. Misalnya, ini dapat digunakan untuk menambahkan header HTTP kustom ke permintaan. `mapRequest`Fungsi menerima callable yang menerima `Psr\Http\Message\RequestInterface` argumen dan mengembalikan objek. `Psr\Http\Message\RequestInterface`

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

Sekarang ketika perintah dijalankan, itu dikirim dengan header khusus.

**penting**  
Perhatikan bahwa middleware ditambahkan ke daftar handler di akhir langkah. `build` Ini untuk memastikan bahwa permintaan telah dibuat sebelum middleware ini dipanggil.

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

`Aws\Middleware::mapResult`Middleware berguna ketika Anda perlu memodifikasi hasil eksekusi perintah. `mapResult`Fungsi menerima callable yang menerima `Aws\ResultInterface` argumen dan mengembalikan objek. `Aws\ResultInterface`

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

Sekarang ketika perintah dijalankan, hasil yang dikembalikan akan berisi `foo` atribut.

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

`history`Middleware berguna untuk menguji bahwa SDK menjalankan perintah yang Anda harapkan, mengirim permintaan HTTP yang Anda harapkan, dan menerima hasil yang Anda harapkan. Ini pada dasarnya middleware yang bertindak mirip dengan sejarah browser web.

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

Kontainer `Aws\History` riwayat menyimpan 10 entri secara default sebelum membersihkan entri. Anda dapat menyesuaikan jumlah entri dengan meneruskan jumlah entri untuk bertahan ke konstruktor.

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

Anda dapat memeriksa wadah riwayat setelah mengeksekusi permintaan yang melewati middleware riwayat.

```
// 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();
```

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

`tap`Middleware digunakan sebagai pengamat. Anda dapat menggunakan middleware ini untuk menjalankan fungsi saat mengirim perintah melalui rantai middleware. `tap`Fungsi menerima callable yang menerima `Aws\CommandInterface` dan opsional `Psr\Http\Message\RequestInterface` yang sedang dijalankan.

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

## Membuat handler kustom
<a name="creating-custom-handlers"></a>

Handler hanyalah fungsi yang menerima objek dan `Aws\CommandInterface` `Psr\Http\Message\RequestInterface` objek, dan mengembalikan a `GuzzleHttp\Promise\PromiseInterface` yang dipenuhi dengan `Aws\ResultInterface` atau ditolak dengan. `Aws\Exception\AwsException`

Meskipun SDK memiliki beberapa `@http` opsi, penangan hanya perlu mengetahui cara menggunakan opsi berikut:
+  [connect\_timeout](guide_configuration.md#http-connect-timeout) 
+  [debug](guide_configuration.md#http-debug) 
+  [decode\_content](guide_configuration.md#http-decode-content) (opsional)
+  [delay](guide_configuration.md#http-delay) 
+  [kemajuan](guide_configuration.md#http-progress) (opsional)
+  [proksi](guide_configuration.md#http-proxy) 
+  [wastafel](guide_configuration.md#http-sink) 
+  [sinkron](guide_configuration.md#http-sync) (opsional)
+  [aliran](guide_configuration.md#http-stream) (opsional)
+  [batas waktu](guide_configuration.md#http-timeout) 
+  [verifikasi](guide_configuration.md#http-verify) 
+ [http\_stats\_receiver (opsional) - Fungsi untuk memanggil dengan array asosiatif statistik transfer HTTP jika diminta menggunakan parameter konfigurasi statistik.](guide_configuration.md#config-stats)

Kecuali jika opsi ditentukan sebagai opsional, penangan HARUS dapat menangani opsi atau HARUS mengembalikan janji yang ditolak.

Selain menangani `@http` opsi tertentu, handler HARUS menambahkan `User-Agent` header yang mengambil formulir berikut, di mana “3.X” dapat diganti dengan `Aws\Sdk::VERSION` dan “HandlerSpecificData/version...” harus diganti dengan string User-Agent khusus penangan Anda.

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