AWS SDK for PHP バージョン 3 でのページネーター - AWS SDK for PHP

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

AWS SDK for PHP バージョン 3 でのページネーター

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

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

$results = $s3Client->getPaginator('ListObjects', [ 'Bucket' => 'my-bucket' ]); foreach ($results as $result) { foreach ($result['Contents'] as $object) { echo $object['Key'] . "\n"; } }

ページネーターオブジェクト

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

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

結果からのデータの列挙

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

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

$results = $s3Client->getPaginator('ListObjects', [ 'Bucket' => 'my-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' => 'my-bucket', 'Delimiter' => '/' ]); $expression = '[CommonPrefixes[].Prefix, Contents[].Key][]'; foreach ($results->search($expression) as $item) { echo $item . "\n"; }

非同期ページ割り

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

$results = $s3Client->getPaginator('ListObjects', [ 'Bucket' => 'my-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' => 'my-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();