

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS SDK for PHP バージョン 3 でページ分割された結果を使用する
<a name="guide_paginators"></a>

一部の AWS サービスオペレーションではページ分割され、結果が一部切り捨てられて応答します。例えば、Amazon S3 の `ListObjects` オペレーションが一度に返すことができるオブジェクトは最大で 1,000 個です。このようなオペレーション (通常は名前が「list」や「describe」で始まる) では、結果セット全体を取得するために、後続のリクエストでトークン (マーカー) パラメータを指定する必要があります。

 **ページネーター**は AWS SDK for PHP の機能で、開発者がページ分割 API を簡単に使用できるようにこのプロセスを抽象化します。ページネーターは、実質的には結果のイテレーターです。ページネーターは、クライアントの `getPaginator()` メソッドを使用して作成されます。`getPaginator()` を呼び出す際に、オペレーションの名前とオペレーションの引数を (オペレーションを実行する場合と同じ方法で) 指定する必要があります。`foreach` を使用してページネーターオブジェクトを反復処理して、個々の `Aws\Result` オブジェクトを取得します。

```
$results = $s3Client->getPaginator('ListObjects', [
    'Bucket' => 'amzn-s3-demo-bucket'
]);

foreach ($results as $result) {
    foreach ($result['Contents'] as $object) {
        echo $object['Key'] . "\n";
    }
}
```

## ページネーターオブジェクト
<a name="paginator-objects"></a>

`getPaginator()` メソッドによって返されるオブジェクトは、`Aws\ResultPaginator` クラスのインスタンスです。このクラスでは、PHP のネイティブの `iterator` インターフェイスが実装されているため、`foreach` で機能します。また、`iterator_to_array` などのイテレーター関数で使用したり、[ オブジェクトなどの ](http://www.php.net/manual/en/spl.iterators.php)SPL イテレーター`LimitIterator`と組み合わせたりできます。

ページネーターオブジェクトは、結果の「ページ」を一度に 1 ページのみ保持し、遅延して実行されます。つまり、ページネーターは、結果の現在のページを生成するのに必要な数のリクエストを作成します。例えば、Amazon S3 の `ListObjects` オペレーションは一度に最大 1,000 個のオブジェクトのみを返すため、バケットに 10,000 個以下のオブジェクトがある場合、ページネーターは合計 10 回のリクエストを行う必要があります。結果を反復処理する場合、反復処理を開始したときに最初のリクエストが実行され、ループの 2 回目の反復で 2 つ目のリクエストが実行されます。

## 結果からのデータの列挙
<a name="enumerating-data-from-results"></a>

ページネーターオブジェクトには、結果の 1 つのセット内のデータに対するイテレーターを作成できる `search()` という名前のメソッドがあります。`search()` を呼び出す際に、抽出するデータを指定するための [JMESPath 式](guide_jmespath.md)を指定します。`search()` を呼び出すと、結果の各ページに対する式の結果を生成するイテレーターが返されます。これは、返されたイテレーターを反復処理するときに、遅延して評価されます。

次の例は、前のコード例と同等ですが、より簡潔にするために `ResultPaginator::search()` メソッドを使用しています。

```
$results = $s3Client->getPaginator('ListObjects', [
    'Bucket' => 'amzn-s3-demo-bucket'
]);

foreach ($results->search('Contents[].Key') as $key) {
    echo $key . "\n";
}
```

JMESPath 式を使用すると、かなり複雑なことを行うことができます。たとえば、すべてのオブジェクトキーおよび共通のプレフィックス (つまり、バケットの `ls`) を出力する場合は、次のようにします。

```
// List all prefixes ("directories") and objects ("files") in the bucket
$results = $s3Client->getPaginator('ListObjects', [
    'Bucket'    => 'amzn-s3-demo-bucket',
    'Delimiter' => '/'
]);

$expression = '[CommonPrefixes[].Prefix, Contents[].Key][]';
foreach ($results->search($expression) as $item) {
    echo $item . "\n";
}
```

## 非同期ページ割り
<a name="async-paginators"></a>

`each()` の `Aws\ResultPaginator` メソッドのコールバックを指定することによって、ページネーターの結果を非同期に反復処理できます。そのコールバックは、ページネーターで生成される値ごとに呼び出されます。

```
$results = $s3Client->getPaginator('ListObjects', [
    'Bucket' => 'amzn-s3-demo-bucket'
]);

$promise = $results->each(function ($result) {
    echo 'Got ' . var_export($result, true) . "\n";
});
```

**注記**  
`each()` メソッドを使用すると、同時に他のリクエストを非同期に送信しながら、API オペレーションの結果をページ分割できます。

そのコールバックからの Null 以外の戻り値は、基になるコルーチンベースの promise によって生成されます。つまり、残っている項目の反復処理を続行する (実質的には他の promise を反復にマージして) 前に、解決する必要があるコールバックから promise を返すことができます。コールバックによって返された直前の Null 以外の値は、promise を任意のダウンストリーム promise に対して満たした結果です。直前の戻り値が promise である場合、その promise の解決はダウンストリーム promise を満たすかまたは拒否した結果です。

```
// Delete all keys that end with "Foo"
$promise = $results->each(function ($result) use ($s3Client) {
    if (substr($result['Key'], -3) === 'Foo') {
        // Merge this promise into the iterator
        return $s3Client->deleteAsync([
            'Bucket' => 'amzn-s3-demo-bucket',
            'Key'    => 'Foo'
        ]);
    }
});

$promise
    ->then(function ($result) {
        // Result would be the last result to the deleteAsync operation
    })
    ->otherwise(function ($reason) {
        // Reason would be an exception that was encountered either in the
        // call to deleteAsync or calls performed while iterating
    });

// Forcing a synchronous wait will also wait on all of the deleteAsync calls
$promise->wait();
```