本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
第 3 AWS SDK for PHP 版中的分頁程式
有些 AWS 服務操作會分頁,並以截斷的結果回應。例如,Amazon S3ListObjects
操作一次最多只會傳回 1,000 個物件。類似這些 (名稱前方通常會加上「列出」或「描述」) 的操作需要以字符 (或標記) 參數進行後續請求,以擷取整組結果。
分頁程式是 的一項功能 AWS SDK for PHP ,可做為此程序的抽象概念,讓開發人員更輕鬆地使用分頁 APIs。分頁程式基本上是結果的疊代運算。它們是透過用戶端的 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"; } }
分頁程式物件
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' => '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"; }
非同步分頁
您可以提供 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 操作的結果進行分頁,同時以非同步方式傳送其他請求。
底層以 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' => '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();