本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
第 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();