Befehlsobjekte in derAWS SDK for PHPVersion 3 - AWS SDK for PHP

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Befehlsobjekte in derAWS SDK for PHPVersion 3

AWS SDK for PHP verwendet das Befehlsmuster, um die Parameter und den Handler einzukapseln, die verwendet werden, um eine HTTP-Anforderung zu einem späteren Zeitpunkt zu übertragen.

Implizite Verwendung von Befehlen

Wenn Sie eine Clientklasse untersuchen, können Sie sehen, dass die den API-Operationen entsprechenden Methoden tatsächlich nicht vorhanden sind. Sie werden mit der magischen Methode __call() umgesetzt. Diese Pseudo-Methoden sind eigentlich Verknüpfungen, die die Verwendung von Befehlsobjekten durch das SDK einkapseln.

In der Regel müssen Sie nicht direkt mit Befehlsobjekten interagieren. Wenn Sie Methoden wie Aws\S3\S3Client::putObject() aufrufen, erstellt das SDK basierend auf den angegebenen Parametern ein Objekt Aws\CommandInterface, führt den Befehl aus und gibt ein ausgefülltes Objekt Aws\ResultInterface zurück (oder löst eine Ausnahme aus, wenn ein Fehler auftritt). Ein ähnlicher Ablauf tritt auf, wenn eine der Async-Methoden eines Clients (z. B. Aws\S3\S3Client::putObjectAsync()) aufgerufen wird: Der Client erstellt einen Befehl basierend auf den bereitgestellten Parametern, serialisiert eine HTTP-Anforderung, initiiert die Anforderung und gibt ein Promise zurück.

Die folgenden Beispiele sind funktional äquivalent.

$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);

Befehlsparameter

Alle Befehle unterstützen einige spezielle Parameter, die nicht Teil der API eines Services sind, sondern das Verhalten des SDK steuern.

@http

Mit diesem Parameter können Sie genau festlegen, wie der zugrunde liegende HTTP-Handler die Anfrage ausführt. Die Optionen, die Sie in den Parameter @httpaufnehmen können, entsprechen denen, die Sie beim Initialisieren des Clients mit der Client-Option „http“ festlegen können.

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

@retries

Wie auch die Client-Option „Wiederholungen“ steuert @retries, wie oft ein Befehl wiederholt werden kann, bevor er als fehlgeschlagen gilt. Setzen Sie es auf 0, um die Versuche zu deaktivieren.

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

Wenn Sie Neuversuche auf einem Client deaktiviert haben, können Sie sie nicht selektiv für einzelne Befehle aktivieren, die an diesen Client übergeben werden.

Erstellen von Befehlsobjek

Sie können einen Befehl mit der getCommand()-Methode eines Clients erstellen. Diese führt nicht sofort eine HTTP-Anfrage aus oder überträgt sie, sondern sie wird nur ausgeführt, wenn sie an die execute()-Methode des Clients übergeben wird. Dies gibt Ihnen die Möglichkeit, das Befehlsobjekt vor der Ausführung des Befehls zu ändern.

$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);

BefehlHandlerList

Wenn ein Befehl von einem Client erstellt wird, erhält er einen Klon des Aws\HandlerList-Objekts des Clients. Der Befehl erhält einen Klon der Handlerliste des Clients, damit ein Befehl benutzerdefinierte Middleware und Handler verwenden kann, die andere vom Client ausgeführte Befehle nicht beeinflussen.

Dies bedeutet, dass Sie einen anderen HTTP-Client pro Befehl (z. B. Aws\MockHandler) verwenden und benutzerdefiniertes Verhalten pro Befehl über Middleware hinzufügen können. Im folgenden Beispiel wird eine MockHandler verwendet, um Scheinergebnisse anstelle von tatsächlichen HTTP-Anforderungen zu erstellen.

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'

Zusätzlich zum Ändern des vom Befehl verwendeten Handlers können Sie dem Befehl auch benutzerdefinierte Middleware hinzufügen. Das folgende Beispiel verwendet die Middleware tap, die als Beobachter in der Handlerliste fungiert.

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

Mit der Aws\CommandPool können Sie Befehle gleichzeitig mit einem Iterator ausführen, der Aws\CommandInterface-Objekte liefert. Die CommandPool stellt sicher, dass eine konstante Anzahl von Befehlen gleichzeitig ausgeführt wird, während über die Befehle im Pool iteriert wird (wenn Befehle abgeschlossen sind, werden mehr ausgeführt, um eine konstante Poolgröße sicherzustellen).

Hier ist ein sehr einfaches Beispiel, um nur einige Befehle mit einer CommandPool zu senden.

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

Dieses Beispiel ist für die CommandPool ziemlich unterentwickelt. Versuchen wir es mit einem komplexeren Beispiel. Nehmen wir an, Sie möchten Dateien auf der Festplatte in einen Amazon S3 S3-Bucket hochladen. Um eine Liste der Dateien von der Festplatte zu erhalten, können wir DirectoryIterator von PHP verwenden. Dieser Iterator liefert SplFileInfo Objekte. Der CommandPool akzeptiert einen Iterator, der Aws\CommandInterface-Objekte liefert, also bilden wir die SplFileInfo-Objekte ab, um Aws\CommandInterface-Objekte zurückzugeben.

<?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"; });

CommandPoolAufbau

Der Aws\CommandPool Konstruktor akzeptiert verschiedene Konfigurationsoptionen.

Nebenläufigkeit (aufrufbar|int)

Maximale Anzahl von Befehlen, die gleichzeitig ausgeführt werden. Stellen Sie eine Funktion bereit, um den Pool dynamisch zu skalieren. Der Funktion wird die aktuelle Anzahl der ausstehenden Anforderungen bereitgestellt, und es wird erwartet, dass sie eine Ganzzahl zurückgibt, die die neue Größe des Pools darstellt.

vor der Aktualisierung (abrufbar)

Funktion, die vor dem Senden jedes Befehls aufgerufen wird. Die before Funktion akzeptiert den Befehl und den Schlüssel des Iterators des Befehls. Sie können den Befehl nach Bedarf in der Funktion before mutieren, bevor Sie den Befehl senden.

erfüllt (aufrufbar)

Funktion, die aufgerufen wird, wenn ein Promise erfüllt ist. Die Funktion enthält das Ergebnisobjekt, die ID des Iterators, von dem das Ergebnis stammt, und das zusammengefasste Promise, das aufgelöst oder zurückgewiesen werden kann, wenn der Pool kurzgeschlossen werden muss.

abgelehnt (Callable)

Funktion, die aufgerufen wird, wenn ein Promise abgelehnt wird. Der Funktion wird ein Aws\ExceptionObjekt zur Verfügung gestellt, die ID des Iterators, von der die Ausnahme kam, und das zusammengefasste Promise, das aufgelöst oder zurückgewiesen werden kann, wenn der Pool kurzgeschlossen werden muss.

Manuelles Garbage Collection zwischen Befehlen

Wenn Sie bei großen Befehlspools das Speicherlimit ausreizen, ist die unter Umstände auf zyklische Referenzen zurückzuführen, die vom SDK konfiguriert wurden und noch nicht von der PHP-Speicherbereinigung gelöscht wurden, als das Speicherlimit erreicht wurde. Manuelles Aufrufen des Bereinigungsalgorithmus zwischen Befehlen ermöglicht unter Umständen die Löschung der Zyklen, bevor das Limit erreicht wird. Das folgende Beispiel erstellt einen CommandPool, der den Bereinigungsalgorithmus mithilfe eines Callbacks aufruft, bevor er die einzelnen Befehle versendet. Beachten Sie, dass das Aufrufen der Speicherbereinigung zulasten der Leistung geht und die optimale Nutzung von Ihrem Anwendungsfall und Ihrer Umgebung abhängt.

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