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 nella AWS SDK for PHP versione 3
AWS SDK for PHP utilizza il modello di comando
Uso implicito dei comandi
Se esamini una classe client, puoi vedere che i metodi corrispondenti alle API operazioni in realtà non esistono. La loro implementazione avviene utilizzando il metodo magico __call()
. Questi pseudo-metodi sono in realtà scorciatoie che incapsulano l'uso degli SDK oggetti di comando.
In genere, non è necessario interagire direttamente con gli oggetti di comando. Quando si chiamano metodi comeAws\S3\S3Client::putObject()
, SDK in realtà crea un Aws\CommandInterface
oggetto in base ai parametri forniti, esegue il comando e restituisce un Aws\ResultInterface
oggetto popolato (o genera un'eccezione in caso di errore). Un flusso simile si verifica quando si chiama uno qualsiasi dei Async
metodi di un client (ad esempio,Aws\S3\S3Client::putObjectAsync()
): il client crea un comando in base ai parametri forniti, serializza una HTTP richiesta, 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 servizio API ma ne controllano invece il SDK comportamento.
@http
Utilizzando questo parametro, è possibile ottimizzare il modo in cui il HTTP gestore 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 HTTP richiesta, ma viene eseguita solo quando viene passata al execute()
metodo 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);
Comando HandlerList
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.
Ciò significa che è possibile utilizzare un HTTP client diverso per comando (ad esempioAws\MockHandler
) e aggiungere un comportamento personalizzato per comando tramite il middleware. L'esempio seguente utilizza MockHandler
a per creare risultati fittizi invece di inviare richieste effettive. HTTP
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. Supponiamo che tu voglia caricare file su disco in un bucket Amazon S3. Per ottenere un elenco di file dal disco, possiamo usare PHP's. DirectoryIterator
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 = 'amzn-s3-demo-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 funzionebefore
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 si raggiunge il limite di memoria con pool di comandi di grandi dimensioni, ciò può essere dovuto ai riferimenti ciclici generati da dati SDK non ancora raccolti dal PHPGarbage Collector al momento del raggiungimentoCommandPool
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(); } ]);