Paginadores en el versión 3 - AWS SDK for PHP

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Paginadores en el versión 3

Algunas operaciones de servicios de AWS están paginadas y responden con resultados truncados. Por ejemplo, la operación de Amazon S3ListObjects solo devuelve un máximo de 1.000 objetos a la vez. Las operaciones como estas (normalmente con el prefijo "lista" o "describir") requieren solicitudes posteriores con parámetros de token (o marcador) para obtener todo el conjunto de resultados.

Los paginadores son una característica del AWS SDK for PHP que actúa como una abstracción de este proceso para facilitar a los desarrolladores el uso de API paginadas. Un paginador es básicamente un iterador de resultados. Se crea con el método getPaginator() del cliente. Cuando llama a getPaginator() debe proporcionar el nombre de la operación y los argumentos de la operación (del mismo modo que lo hace al ejecutar una operación). Puede iterar sobre un objeto de paginador con foreach para obtener objetos Aws\Result individuales.

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

Objetos de paginador

El objeto que el método getPaginator() devuelve es una instancia de la clase Aws\ResultPaginator. Esta clase implementa la interfaz iterator nativa de PHP, motivo por el cual funciona con foreach. También se puede utilizar con funciones de iterador, como iterator_to_array, y se integra bien con iteradores SPL como el objeto LimitIterator.

Los objetos del paginador solo contienen una "página" de resultados a la vez y se ejecutan lentamente. Esto significa que realizan solo tantas solicitudes como necesitan para obtener la página actual de resultados. Por ejemplo, la operación de Amazon S3ListObjects solo devuelve un máximo de 1.000 objetos a la vez, por lo que si tu bucket tiene ~10.000 objetos, el paginador debería hacer 10 peticiones en total. Cuando itera los resultados, la primera solicitud se ejecuta cuando comienza la iteración, la segunda en la segunda iteración del bucle, y así sucesivamente.

Enumeración de datos a partir de los resultados

Los objetos del paginador tienen un método llamado search() que le permiten crear iteradores para datos que están en un conjunto de resultados. Cuando llame a search() proporcione una expresión JMESPath para especificar los datos que deben extraerse. Llamar a search() devuelve un iterador que genera los resultados de la expresión en cada página de resultados. Esto se evalúa lentamente, a medida que recorre el iterador devuelto.

El siguiente ejemplo es equivalente al ejemplo de código anterior, pero utiliza el método ResultPaginator::search() para ser más conciso.

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

Las expresiones JMESPath le permiten realizar operaciones bastante complejas. Por ejemplo, si desea imprimir todas las claves de objetos y prefijos habituales (es decir, hacer un ls de un bucket), puede hacer lo siguiente.

// 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"; }

Paginación asíncrona

Puede iterar a través de los resultados de un paginador de forma asíncrona proporcionando una devolución de llamada para el método each() de un Aws\ResultPaginator. La devolución de llamada se invoca para cada valor que el paginador genera.

$results = $s3Client->getPaginator('ListObjects', [ 'Bucket' => 'my-bucket' ]); $promise = $results->each(function ($result) { echo 'Got ' . var_export($result, true) . "\n"; });
nota

Con el método each() se puede paginar por los resultados de una operación de la API y enviar al mismo tiempo otras solicitudes de forma asíncrona.

La promesa basada en la corutina subyacente generará un valor de retorno no nulo a partir de la devolución de llamada. Esto significa que puede devolver promesas desde la devolución de llamada que deben resolverse antes de continuar la iteración por los elementos restantes, básicamente combinando otras promesas a la iteración. El último valor no nulo que devuelve la devolución de llamada es el resultado que responde a la promesa de todas las promesas posteriores. Si el último valor devuelto es una promesa, la resolución de esa promesa es el resultado que responde a las promesas posteriores o las rechaza.

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