Oggetti di comando inAWS SDK for PHPVersione 3 - AWS SDK for PHP

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Oggetti di comando inAWS SDK for PHPVersione 3

AWS SDK for PHP utilizza il modello dei comandi per incapsulare i parametri e il gestore da utilizzare per trasferire una richiesta HTTP in un momento successivo.

Uso implicito dei comandi

Se si esaminano le classi di client, è possibile vedere che i metodi corrispondenti alle operazioni delle API in realtà non esistono. La loro implementazione avviene utilizzando il metodo magico __call(). Questi pseudo-metodi sono in realtà collegamenti che incapsulano l'utilizzo degli oggetti di comando di SDK.

In genere, non è necessario interagire direttamente con gli oggetti di comando. Quando si chiamano metodi come Aws\S3\S3Client::putObject(), in realtà SDK crea un Aws\CommandInterface in base ai parametri forniti, esegue il comando e restituisce un oggetto Aws\ResultInterface popolato (o genera un'eccezione in caso di errore). Un flusso simile si verifica quando viene chiamato un metodo Async di un client (ad esempio, Aws\S3\S3Client::putObjectAsync()): il client crea un comando in base ai parametri forniti, serializza una richiesta HTTP, avvia la richiesta e restituisce una promessa.

I seguenti esempi sono equivalenti da un punto di vista funzionale.

$s3Client = new Aws\S3\S3Client([ 'version' => '2006-03-01', 'region' => 'us-standard' ]); $params = [ 'Bucket' => 'foo', 'Key' => 'baz', 'Body' => 'bar' ]; // Using operation methods creates a command implicitly $result = $s3Client->putObject($params); // Using commands explicitly $command = $s3Client->getCommand('PutObject', $params); $result = $s3Client->execute($command);

parametri di comando

Tutti i comandi supportano alcuni parametri speciali che non fanno parte di un'API del servizio, ma che controllano invece il comportamento di SDK.

@http

Quando si utilizza questo parametro, è possibile ottimizzare il modo in cui il gestore HTTP sottostante esegue la richiesta. Le opzioni che possono essere incluse nel parametro @http sono le stesse che possono essere impostate quando si crea un'istanza del client con l'opzione client "http".

// Configures the command to be delayed by 500 milliseconds $command['@http'] = [ 'delay' => 500, ];

@retries

Come nel caso dell'opzione client "nuovi tentativi", @retries controlla il numero massimo di nuovi tentativi di un comando prima che venga considerato non riuscito. Impostalo su 0 per disabilitare i nuovi tentativi.

// Disable retries $command['@retries'] = 0;
Nota

Se i nuovi tentativi sono stati disabilitati per un client, non è possibile abilitarli in modo selettivo su singoli comandi passati al client in questione.

Creazione di oggetti di comando

È possibile creare un comando utilizzando il metodo getCommand() di un client. Non esegue o trasferisce immediatamente una richiesta HTTP, ma viene eseguito soltanto quando viene passato al metodo execute() del client. In questo modo, è possibile modificare l'oggetto di comando prima di eseguire il comando.

$command = $s3Client->getCommand('ListObjects'); $command['MaxKeys'] = 50; $command['Prefix'] = 'foo/baz/'; $result = $s3Client->execute($command); // You can also modify parameters $command = $s3Client->getCommand('ListObjects', [ 'MaxKeys' => 50, 'Prefix' => 'foo/baz/', ]); $command['MaxKeys'] = 100; $result = $s3Client->execute($command);

ComandoHandlerList

Quando un comando viene creato da un client, gli viene assegnato un clone dell'oggetto Aws\HandlerList del client. Al comando viene assegnato un clone dell'elenco dei gestori del client per consentire a un comando di utilizzare middleware e gestori personalizzati che non interessano altri comandi eseguiti dal client.

In questo modo, è possibile utilizzare un client HTTP diverso per ogni comando (ad esempio, Aws\MockHandler) e aggiungere un comportamento personalizzato per ogni comando tramite middleware. I seguenti esempi utilizzano un MockHandler per creare risultati fittizi anziché inviare richieste HTTP effettive.

use Aws\Result; use Aws\MockHandler; // Create a mock handler $mock = new MockHandler(); // Enqueue a mock result to the handler $mock->append(new Result(['foo' => 'bar'])); // Create a "ListObjects" command $command = $s3Client->getCommand('ListObjects'); // Associate the mock handler with the command $command->getHandlerList()->setHandler($mock); // Executing the command will use the mock handler, which returns the // mocked result object $result = $client->execute($command); echo $result['foo']; // Outputs 'bar'

Oltre a modificare il gestore utilizzato dal comando, è anche possibile includere un middleware personalizzato nel comando. L'esempio seguente utilizza il middleware tap, che funge da osservatore nell'elenco dei gestori.

use Aws\CommandInterface; use Aws\Middleware; use Psr\Http\Message\RequestInterface; $command = $s3Client->getCommand('ListObjects'); $list = $command->getHandlerList(); // Create a middleware that just dumps the command and request that is // about to be sent $middleware = Middleware::tap( function (CommandInterface $command, RequestInterface $request) { var_dump($command->toArray()); var_dump($request); } ); // Append the middleware to the "sign" step of the handler list. The sign // step is the last step before transferring an HTTP request. $list->append('sign', $middleware); // Now transfer the command and see the var_dump data $s3Client->execute($command);

CommandPool

Aws\CommandPool consente di eseguire comandi simultaneamente utilizzando un'iterazione che produce oggetti Aws\CommandInterface. CommandPool garantisce che un numero costante di comandi venga eseguito simultaneamente durante l'iterazione sui comandi nel pool (mentre i comandi vengono completati, ne vengono eseguiti altri per garantire dimensioni del pool costanti).

Di seguito è riportato un semplice esempio di invio di alcuni comandi utilizzando CommandPool.

use Aws\S3\S3Client; use Aws\CommandPool; // Create the client $client = new S3Client([ 'region' => 'us-standard', 'version' => '2006-03-01' ]); $bucket = 'example'; $commands = [ $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'a']), $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'b']), $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'c']) ]; $pool = new CommandPool($client, $commands); // Initiate the pool transfers $promise = $pool->promise(); // Force the pool to complete synchronously $promise->wait();

Questo esempio per CommandPool è piuttosto elementare. L'esempio seguente è più complesso. Si supponga di voler caricare file su disco in un bucket Amazon S3. Per ottenere un elenco dei file del disco, è possibile utilizzare la funzione DirectoryIterator di PHP. Questa iterazione genera oggetti SplFileInfo. CommandPool accetta un'iterazione che genera oggetti Aws\CommandInterface, perciò occorre eseguire la mappatura sugli oggetti SplFileInfo per restituire oggetti Aws\CommandInterface.

<?php require 'vendor/autoload.php'; use Aws\Exception\AwsException; use Aws\S3\S3Client; use Aws\CommandPool; use Aws\CommandInterface; use Aws\ResultInterface; use GuzzleHttp\Promise\PromiseInterface; // Create the client $client = new S3Client([ 'region' => 'us-standard', 'version' => '2006-03-01' ]); $fromDir = '/path/to/dir'; $toBucket = 'my-bucket'; // Create an iterator that yields files from a directory $files = new DirectoryIterator($fromDir); // Create a generator that converts the SplFileInfo objects into // Aws\CommandInterface objects. This generator accepts the iterator that // yields files and the name of the bucket to upload the files to. $commandGenerator = function (\Iterator $files, $bucket) use ($client) { foreach ($files as $file) { // Skip "." and ".." files if ($file->isDot()) { continue; } $filename = $file->getPath() . '/' . $file->getFilename(); // Yield a command that is executed by the pool yield $client->getCommand('PutObject', [ 'Bucket' => $bucket, 'Key' => $file->getBaseName(), 'Body' => fopen($filename, 'r') ]); } }; // Now create the generator using the files iterator $commands = $commandGenerator($files, $toBucket); // Create a pool and provide an optional array of configuration $pool = new CommandPool($client, $commands, [ // Only send 5 files at a time (this is set to 25 by default) 'concurrency' => 5, // Invoke this function before executing each command 'before' => function (CommandInterface $cmd, $iterKey) { echo "About to send {$iterKey}: " . print_r($cmd->toArray(), true) . "\n"; }, // Invoke this function for each successful transfer 'fulfilled' => function ( ResultInterface $result, $iterKey, PromiseInterface $aggregatePromise ) { echo "Completed {$iterKey}: {$result}\n"; }, // Invoke this function for each failed transfer 'rejected' => function ( AwsException $reason, $iterKey, PromiseInterface $aggregatePromise ) { echo "Failed {$iterKey}: {$reason}\n"; }, ]); // Initiate the pool transfers $promise = $pool->promise(); // Force the pool to complete synchronously $promise->wait(); // Or you can chain the calls off of the pool $promise->then(function() { echo "Done\n"; });

Configurazione CommandPool

Il costruttore Aws\CommandPool accetta varie opzioni di configurazione.

concurrency (callable|int)

Numero massimo di comandi da eseguire simultaneamente. È possibile fornire una funzione per ridimensionare il pool in modo dinamico. La funzione include l'attuale numero di richieste in sospeso e dovrebbe restituire un numero intero che rappresenta il nuovo limite delle dimensioni del pool.

before (callable)

Funzione che consente di eseguire l'invocazione prima dell'invio di un comando. La funzione before accetta il comando e la chiave dell'iterazione del comando. È possibile modificare il comando secondo necessità nella funzione before prima di inviare il comando.

fulfilled (callable)

Funzione che consente di effettuare l'invocazione quando una promessa viene soddisfatta. La funzione include l'oggetto risultato, l'ID dell'iterazione da cui proveniva il risultato e la promessa in forma aggregata che può essere risolta o respinta se occorre cortocircuitare il pool.

rejected (callable)

Funzione che consente di effettuare l'invocazione quando una promessa viene respinta. La funzione include un oggetto Aws\Exception, l'ID dell'iterazione da cui proveniva l'eccezione e la promessa in forma aggregata che può essere risolta o respinta se occorre cortocircuitare il pool.

Raccolta manuale dei rifiuti tra i comandi

Se pool di comandi di grandi dimensioni causano il raggiungimento del limite di memoria, la causa è da ricercarsi nei riferimenti ciclici generati dall'SDK che non sono ancora stati raccolti dal garbage collector PHP quando il limite di memoria è stato raggiunto. L'invocazione manuale dell'algoritmo di raccolta tra i comandi può consentire la raccolta dei cicli prima del raggiungimento di tale limite. L'esempio seguente crea un CommandPool che richiama l'algoritmo di raccolta utilizzando un callback prima dell'invio di ogni comando. L'invocazione di garbage collector comporta costi di prestazioni e l'uso ottimale dipende dal caso d'uso e dall'ambiente.

$pool = new CommandPool($client, $commands, [ 'concurrency' => 25, 'before' => function (CommandInterface $cmd, $iterKey) { gc_collect_cycles(); } ]);