第 3AWS SDK for PHP 版中的分頁器 - AWS SDK for PHP

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

第 3AWS SDK for PHP 版中的分頁器

部分AWS服務作業會分頁,並以截斷的結果回應。例如,Amazon S3ListObjects 作業一次最多只能傳回 1,000 個物件。類似這些 (名稱前方通常會加上「列出」或「描述」) 的操作需要以字符 (或標記) 參數進行後續請求,以擷取整組結果。

分頁程式是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 物件。

分頁程式物件一次只能保留一個結果的「頁面」,並且會延遲執行。這表示它們只會執行所需的請求,以產生結果的目前頁面。例如,Amazon S3ListObjects 操作一次最多只能返回 1,000 個物件,因此,如果您的儲存貯體有大約 10,000 個物件,則分頁器總共需要執行 10 個請求。當您逐一查看結果時,第一個請求會在您開始查看時執行,第二個請求在第二次查看時執行,以此類推。

從結果枚舉數據

分頁程式物件有一個名為 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 操作的結果進行分頁,同時以非同步方式傳送其他請求。

底層以 coroutine 為基礎的承諾將會產生來自回呼的非 null 傳回值。這表示您可以從回呼傳回承諾,此回呼必須先解決再能繼續逐一查看其餘項目,基本上就是合併其他承諾至逐一查看。回呼傳回的最後一個非 null 值,是履行承諾至任何下游承諾的結果。如果上個傳回值是一個承諾,該承諾的解析度是履行或拒絕下游承諾的結果。

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